Completed
Push — release/2.0 ( 9c875b...4d845f )
by Ravinder
19:03
created

upgrade-functions.php ➔ give_v20_upgrades_form_metadata()   C

Complexity

Conditions 8
Paths 32

Size

Total Lines 85
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 51
nc 32
nop 0
dl 0
loc 85
rs 5.8037
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
	// v2.0 form metadata upgrades.
139
	if ( version_compare( $give_version, '2.0', '<' ) || ! give_has_upgrade_completed( 'v20_upgrades_form_metadata' ) ) {
140
		echo Give_Notices::notice_html(
141
			sprintf(
142
				esc_html__( 'Give needs to upgrade the form database, click %1$shere%2$s to start the upgrade.', 'give' ),
143
				'<a class="give-upgrade-link" href="' . esc_url( admin_url( 'index.php?page=give-upgrades&give-upgrade=give_v20_upgrades_form_metadata' ) ) . '">',
144
				'</a>'
145
			)
146
		);
147
	}
148
149
	// End 'Stepped' upgrade process notices.
150
	?>
151
	<script>
152
		jQuery(document).ready(function($){
153
			var $upgrade_links = $('.give-upgrade-link');
154
			if( $upgrade_links.length ) {
155
				$upgrade_links.on( 'click', function(e){
156
					e.preventDefault();
157
158
					if( ! window.confirm( '<?php _e( 'Please make sure to create a database backup before initiating the upgrade.', 'give' ); ?>' ) ) {
159
						return;
160
					}
161
162
					// Redirect to upgrdae link.
163
					window.location.assign( $(this).attr('href') );
164
				});
165
			}
166
		});
167
	</script>
168
	<?php
169
}
170
171
add_action( 'admin_notices', 'give_show_upgrade_notices' );
172
173
/**
174
 * Triggers all upgrade functions
175
 *
176
 * This function is usually triggered via AJAX
177
 *
178
 * @since 1.0
179
 * @return void
180
 */
181
function give_trigger_upgrades() {
182
183
	if ( ! current_user_can( 'manage_give_settings' ) ) {
184
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
185
			'response' => 403,
186
		) );
187
	}
188
189
	$give_version = get_option( 'give_version' );
190
191
	if ( ! $give_version ) {
192
		// 1.0 is the first version to use this option so we must add it.
193
		$give_version = '1.0';
194
		add_option( 'give_version', $give_version );
195
	}
196
197
	update_option( 'give_version', GIVE_VERSION );
198
	delete_option( 'give_doing_upgrade' );
199
200
	if ( DOING_AJAX ) {
201
		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...
202
	} // 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...
203
}
204
205
add_action( 'wp_ajax_give_trigger_upgrades', 'give_trigger_upgrades' );
206
207
/**
208
 * Check if the upgrade routine has been run for a specific action
209
 *
210
 * @since  1.0
211
 *
212
 * @param  string $upgrade_action The upgrade action to check completion for
213
 *
214
 * @return bool                   If the action has been added to the completed actions array
215
 */
216
function give_has_upgrade_completed( $upgrade_action = '' ) {
217
218
	if ( empty( $upgrade_action ) ) {
219
		return false;
220
	}
221
222
	$completed_upgrades = give_get_completed_upgrades();
223
224
	return in_array( $upgrade_action, $completed_upgrades );
225
226
}
227
228
/**
229
 * For use when doing 'stepped' upgrade routines, to see if we need to start somewhere in the middle
230
 *
231
 * @since 1.8
232
 *
233
 * @return mixed   When nothing to resume returns false, otherwise starts the upgrade where it left off
234
 */
235
function give_maybe_resume_upgrade() {
236
	$doing_upgrade = get_option( 'give_doing_upgrade', false );
237
	if ( empty( $doing_upgrade ) ) {
238
		return false;
239
	}
240
241
	return $doing_upgrade;
242
}
243
244
/**
245
 * Adds an upgrade action to the completed upgrades array
246
 *
247
 * @since  1.0
248
 *
249
 * @param  string $upgrade_action The action to add to the completed upgrades array
250
 *
251
 * @return bool                   If the function was successfully added
252
 */
253
function give_set_upgrade_complete( $upgrade_action = '' ) {
254
255
	if ( empty( $upgrade_action ) ) {
256
		return false;
257
	}
258
259
	$completed_upgrades   = give_get_completed_upgrades();
260
	$completed_upgrades[] = $upgrade_action;
261
262
	// Remove any blanks, and only show uniques.
263
	$completed_upgrades = array_unique( array_values( $completed_upgrades ) );
264
265
	return update_option( 'give_completed_upgrades', $completed_upgrades );
266
}
267
268
/**
269
 * Get's the array of completed upgrade actions
270
 *
271
 * @since  1.0
272
 * @return array The array of completed upgrades
273
 */
274
function give_get_completed_upgrades() {
275
276
	$completed_upgrades = get_option( 'give_completed_upgrades' );
277
278
	if ( false === $completed_upgrades ) {
279
		$completed_upgrades = array();
280
	}
281
282
	return $completed_upgrades;
283
284
}
285
286
/**
287
 * Upgrades the
288
 *
289
 * Standardizes the discrepancies between two metakeys `_give_payment_customer_id` and `_give_payment_donor_id`
290
 *
291
 * @since      1.3.2
292
 */
293
function give_v132_upgrade_give_payment_customer_id() {
294
	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...
295
	if ( ! current_user_can( 'manage_give_settings' ) ) {
296
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
297
			'response' => 403,
298
		) );
299
	}
300
301
	ignore_user_abort( true );
302
303
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
304
		@set_time_limit( 0 );
305
	}
306
307
	// UPDATE DB METAKEYS.
308
	$sql   = "UPDATE $wpdb->postmeta SET meta_key = '_give_payment_customer_id' WHERE meta_key = '_give_payment_donor_id'";
309
	$query = $wpdb->query( $sql );
310
311
	update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
312
	give_set_upgrade_complete( 'upgrade_give_payment_customer_id' );
313
	delete_option( 'give_doing_upgrade' );
314
	wp_redirect( admin_url() );
315
	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...
316
317
}
318
319
add_action( 'give_upgrade_give_payment_customer_id', 'give_v132_upgrade_give_payment_customer_id' );
320
321
/**
322
 * Upgrades the Offline Status
323
 *
324
 * Reverses the issue where offline donations in "pending" status where inappropriately marked as abandoned
325
 *
326
 * @since      1.3.4
327
 */
328
function give_v134_upgrade_give_offline_status() {
329
330
	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...
331
332
	if ( ! current_user_can( 'manage_give_settings' ) ) {
333
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
334
			'response' => 403,
335
		) );
336
	}
337
338
	ignore_user_abort( true );
339
340
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
341
		@set_time_limit( 0 );
342
	}
343
344
	// Get abandoned offline payments.
345
	$select = "SELECT ID FROM $wpdb->posts p ";
346
	$join   = "LEFT JOIN $wpdb->postmeta m ON p.ID = m.post_id ";
347
	$where  = "WHERE p.post_type = 'give_payment' ";
348
	$where .= "AND ( p.post_status = 'abandoned' )";
349
	$where .= "AND ( m.meta_key = '_give_payment_gateway' AND m.meta_value = 'offline' )";
350
351
	$sql            = $select . $join . $where;
352
	$found_payments = $wpdb->get_col( $sql );
353
354
	foreach ( $found_payments as $payment ) {
355
356
		// Only change ones marked abandoned since our release last week because the admin may have marked some abandoned themselves.
357
		$modified_time = get_post_modified_time( 'U', false, $payment );
358
359
		// 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...
360
		if ( $modified_time >= 1450124863 ) {
361
362
			give_update_payment_status( $payment, 'pending' );
363
364
		}
365
	}
366
367
	update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
368
	give_set_upgrade_complete( 'upgrade_give_offline_status' );
369
	delete_option( 'give_doing_upgrade' );
370
	wp_redirect( admin_url() );
371
	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...
372
373
}
374
375
add_action( 'give_upgrade_give_offline_status', 'give_v134_upgrade_give_offline_status' );
376
377
/**
378
 * Cleanup User Roles
379
 *
380
 * This upgrade routine removes unused roles and roles with typos
381
 *
382
 * @since      1.5.2
383
 */
384
function give_v152_cleanup_users() {
385
386
	$give_version = get_option( 'give_version' );
387
388
	if ( ! $give_version ) {
389
		// 1.0 is the first version to use this option so we must add it.
390
		$give_version = '1.0';
391
	}
392
393
	$give_version = preg_replace( '/[^0-9.].*/', '', $give_version );
394
395
	// v1.5.2 Upgrades
396
	if ( version_compare( $give_version, '1.5.2', '<' ) || ! give_has_upgrade_completed( 'upgrade_give_user_caps_cleanup' ) ) {
397
398
		// Delete all caps with "ss".
399
		// Also delete all unused "campaign" roles.
400
		$delete_caps = array(
401
			'delete_give_formss',
402
			'delete_others_give_formss',
403
			'delete_private_give_formss',
404
			'delete_published_give_formss',
405
			'read_private_forms',
406
			'edit_give_formss',
407
			'edit_others_give_formss',
408
			'edit_private_give_formss',
409
			'edit_published_give_formss',
410
			'publish_give_formss',
411
			'read_private_give_formss',
412
			'assign_give_campaigns_terms',
413
			'delete_give_campaigns',
414
			'delete_give_campaigns_terms',
415
			'delete_give_campaignss',
416
			'delete_others_give_campaignss',
417
			'delete_private_give_campaignss',
418
			'delete_published_give_campaignss',
419
			'edit_give_campaigns',
420
			'edit_give_campaigns_terms',
421
			'edit_give_campaignss',
422
			'edit_others_give_campaignss',
423
			'edit_private_give_campaignss',
424
			'edit_published_give_campaignss',
425
			'manage_give_campaigns_terms',
426
			'publish_give_campaignss',
427
			'read_give_campaigns',
428
			'read_private_give_campaignss',
429
			'view_give_campaigns_stats',
430
			'delete_give_paymentss',
431
			'delete_others_give_paymentss',
432
			'delete_private_give_paymentss',
433
			'delete_published_give_paymentss',
434
			'edit_give_paymentss',
435
			'edit_others_give_paymentss',
436
			'edit_private_give_paymentss',
437
			'edit_published_give_paymentss',
438
			'publish_give_paymentss',
439
			'read_private_give_paymentss',
440
		);
441
442
		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...
443
		foreach ( $delete_caps as $cap ) {
444
			foreach ( array_keys( $wp_roles->roles ) as $role ) {
445
				$wp_roles->remove_cap( $role, $cap );
446
			}
447
		}
448
449
		// Create Give plugin roles.
450
		$roles = new Give_Roles();
451
		$roles->add_roles();
452
		$roles->add_caps();
453
454
		// The Update Ran.
455
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
456
		give_set_upgrade_complete( 'upgrade_give_user_caps_cleanup' );
457
		delete_option( 'give_doing_upgrade' );
458
459
	}// 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...
460
461
}
462
463
add_action( 'admin_init', 'give_v152_cleanup_users' );
464
465
/**
466
 * 1.6 Upgrade routine to create the customer meta table.
467
 *
468
 * @since  1.6
469
 * @return void
470
 */
471
function give_v16_upgrades() {
472
	@Give()->customers->create_table();
473
	@Give()->customer_meta->create_table();
474
}
475
476
/**
477
 * 1.7 Upgrades.
478
 *
479
 * a. Update license api data for plugin addons.
480
 * b. Cleanup user roles.
481
 *
482
 * @since  1.7
483
 * @return void
484
 */
485
function give_v17_upgrades() {
486
	// Upgrade license data.
487
	give_v17_upgrade_addon_license_data();
488
	give_v17_cleanup_roles();
489
}
490
491
/**
492
 * Upgrade license data
493
 *
494
 * @since 1.7
495
 */
496
function give_v17_upgrade_addon_license_data() {
497
	$give_options = give_get_settings();
498
499
	$api_url = 'https://givewp.com/give-sl-api/';
500
501
	// Get addons license key.
502
	$addons = array();
503
	foreach ( $give_options as $key => $value ) {
504
		if ( false !== strpos( $key, '_license_key' ) ) {
505
			$addons[ $key ] = $value;
506
		}
507
	}
508
509
	// Bailout: We do not have any addon license data to upgrade.
510
	if ( empty( $addons ) ) {
511
		return false;
512
	}
513
514
	foreach ( $addons as $key => $addon_license ) {
515
516
		// Get addon shortname.
517
		$shortname = str_replace( '_license_key', '', $key );
518
519
		// Addon license option name.
520
		$addon_license_option_name = $shortname . '_license_active';
521
522
		// bailout if license is empty.
523
		if ( empty( $addon_license ) ) {
524
			delete_option( $addon_license_option_name );
525
			continue;
526
		}
527
528
		// Get addon name.
529
		$addon_name       = array();
530
		$addon_name_parts = explode( '_', str_replace( 'give_', '', $shortname ) );
531
		foreach ( $addon_name_parts as $name_part ) {
532
533
			// Fix addon name
534
			switch ( $name_part ) {
535
				case 'authorizenet' :
536
					$name_part = 'authorize.net';
537
					break;
538
			}
539
540
			$addon_name[] = ucfirst( $name_part );
541
		}
542
543
		$addon_name = implode( ' ', $addon_name );
544
545
		// Data to send to the API
546
		$api_params = array(
547
			'edd_action' => 'activate_license', // never change from "edd_" to "give_"!
548
			'license'    => $addon_license,
549
			'item_name'  => urlencode( $addon_name ),
550
			'url'        => home_url(),
551
		);
552
553
		// Call the API.
554
		$response = wp_remote_post(
555
			$api_url,
556
			array(
557
				'timeout'   => 15,
558
				'sslverify' => false,
559
				'body'      => $api_params,
560
			)
561
		);
562
563
		// Make sure there are no errors.
564
		if ( is_wp_error( $response ) ) {
565
			delete_option( $addon_license_option_name );
566
			continue;
567
		}
568
569
		// Tell WordPress to look for updates.
570
		set_site_transient( 'update_plugins', null );
571
572
		// Decode license data.
573
		$license_data = json_decode( wp_remote_retrieve_body( $response ) );
574
		update_option( $addon_license_option_name, $license_data );
575
	}// 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...
576
}
577
578
579
/**
580
 * Cleanup User Roles.
581
 *
582
 * This upgrade routine removes unused roles and roles with typos.
583
 *
584
 * @since      1.7
585
 */
586
function give_v17_cleanup_roles() {
587
588
	// Delete all caps with "_give_forms_" and "_give_payments_"
589
	// These roles have no usage; the proper is singular.
590
	$delete_caps = array(
591
		'view_give_forms_stats',
592
		'delete_give_forms_terms',
593
		'assign_give_forms_terms',
594
		'edit_give_forms_terms',
595
		'manage_give_forms_terms',
596
		'view_give_payments_stats',
597
		'manage_give_payments_terms',
598
		'edit_give_payments_terms',
599
		'assign_give_payments_terms',
600
		'delete_give_payments_terms',
601
	);
602
603
	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...
604
	foreach ( $delete_caps as $cap ) {
605
		foreach ( array_keys( $wp_roles->roles ) as $role ) {
606
			$wp_roles->remove_cap( $role, $cap );
607
		}
608
	}
609
610
	// Set roles again.
611
	$roles = new Give_Roles();
612
	$roles->add_roles();
613
	$roles->add_caps();
614
615
}
616
617
/**
618
 * 1.8 Upgrades.
619
 *
620
 * a. Upgrade checkbox settings to radio button settings.
621
 * a. Update form meta for new metabox settings.
622
 *
623
 * @since  1.8
624
 * @return void
625
 */
626
function give_v18_upgrades() {
627
	// Upgrade checkbox settings to radio button settings.
628
	give_v18_upgrades_core_setting();
629
}
630
631
/**
632
 * Upgrade core settings.
633
 *
634
 * @since  1.8
635
 * @return void
636
 */
637
function give_v18_upgrades_core_setting() {
638
	// Core settings which changes from checkbox to radio.
639
	$core_setting_names = array_merge(
640
		array_keys( give_v18_renamed_core_settings() ),
641
		array(
642
			'uninstall_on_delete',
643
			'scripts_footer',
644
			'test_mode',
645
			'email_access',
646
			'terms',
647
			'give_offline_donation_enable_billing_fields',
648
		)
649
	);
650
651
	// Bailout: If not any setting define.
652
	if ( $give_settings = get_option( 'give_settings' ) ) {
653
654
		$setting_changed = false;
655
656
		// Loop: check each setting field.
657
		foreach ( $core_setting_names as $setting_name ) {
658
			// New setting name.
659
			$new_setting_name = preg_replace( '/^(enable_|disable_)/', '', $setting_name );
660
661
			// Continue: If setting already set.
662
			if (
663
				array_key_exists( $new_setting_name, $give_settings )
664
				&& in_array( $give_settings[ $new_setting_name ], array( 'enabled', 'disabled' ) )
665
			) {
666
				continue;
667
			}
668
669
			// Set checkbox value to radio value.
670
			$give_settings[ $setting_name ] = ( ! empty( $give_settings[ $setting_name ] ) && 'on' === $give_settings[ $setting_name ] ? 'enabled' : 'disabled' );
671
672
			// @see https://github.com/WordImpress/Give/issues/1063
673
			if ( false !== strpos( $setting_name, 'disable_' ) ) {
674
675
				$give_settings[ $new_setting_name ] = ( give_is_setting_enabled( $give_settings[ $setting_name ] ) ? 'disabled' : 'enabled' );
676
			} elseif ( false !== strpos( $setting_name, 'enable_' ) ) {
677
678
				$give_settings[ $new_setting_name ] = ( give_is_setting_enabled( $give_settings[ $setting_name ] ) ? 'enabled' : 'disabled' );
679
			}
680
681
			// Tell bot to update core setting to db.
682
			if ( ! $setting_changed ) {
683
				$setting_changed = true;
684
			}
685
		}
686
687
		// Update setting only if they changed.
688
		if ( $setting_changed ) {
689
			update_option( 'give_settings', $give_settings );
690
		}
691
	}// 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...
692
693
	give_set_upgrade_complete( 'v18_upgrades_core_setting' );
694
}
695
696
/**
697
 * Upgrade form metadata for new metabox settings.
698
 *
699
 * @since  1.8
700
 * @return void
701
 */
702
function give_v18_upgrades_form_metadata() {
703
	if ( ! current_user_can( 'manage_give_settings' ) ) {
704
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
705
			'response' => 403,
706
		) );
707
	}
708
709
	ignore_user_abort( true );
710
711
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
712
		@set_time_limit( 0 );
713
	}
714
715
	$step = isset( $_GET['step'] ) ? absint( $_GET['step'] ) : 1;
716
717
	// form query
718
	$forms = new WP_Query( array(
719
			'paged'          => $step,
720
			'status'         => 'any',
721
			'order'          => 'ASC',
722
			'post_type'      => 'give_forms',
723
			'posts_per_page' => 20,
724
		)
725
	);
726
727
	if ( $forms->have_posts() ) {
728
		while ( $forms->have_posts() ) {
729
			$forms->the_post();
730
731
			// Form content.
732
			// Note in version 1.8 display content setting split into display content and content placement setting.
733
			// You can delete _give_content_option in future
734
			$show_content = give_get_meta( get_the_ID(), '_give_content_option', true );
735
			if ( $show_content && ! give_get_meta( get_the_ID(), '_give_display_content', true ) ) {
736
				$field_value = ( 'none' !== $show_content ? 'enabled' : 'disabled' );
737
				give_update_meta( get_the_ID(), '_give_display_content', $field_value );
738
739
				$field_value = ( 'none' !== $show_content ? $show_content : 'give_pre_form' );
740
				give_update_meta( get_the_ID(), '_give_content_placement', $field_value );
741
			}
742
743
			// "Disable" Guest Donation. Checkbox
744
			// See: https://github.com/WordImpress/Give/issues/1470
745
			$guest_donation = give_get_meta( get_the_ID(), '_give_logged_in_only', true );
746
			$guest_donation_newval = ( in_array( $guest_donation, array( 'yes', 'on' ) ) ? 'disabled' : 'enabled' );
747
			give_update_meta( get_the_ID(), '_give_logged_in_only', $guest_donation_newval );
748
749
			// Offline Donations
750
			// See: https://github.com/WordImpress/Give/issues/1579
751
			$offline_donation = give_get_meta( get_the_ID(), '_give_customize_offline_donations', true );
752
			if ( 'no' === $offline_donation ) {
753
				$offline_donation_newval = 'global';
754
			} elseif ( 'yes' === $offline_donation ) {
755
				$offline_donation_newval = 'enabled';
756
			} else {
757
				$offline_donation_newval = 'disabled';
758
			}
759
			give_update_meta( get_the_ID(), '_give_customize_offline_donations', $offline_donation_newval );
760
761
			// Convert yes/no setting field to enabled/disabled.
762
			$form_radio_settings = array(
763
				// Custom Amount.
764
				'_give_custom_amount',
765
766
				// Donation Gaol.
767
				'_give_goal_option',
768
769
				// Close Form.
770
				'_give_close_form_when_goal_achieved',
771
772
				// Term & conditions.
773
				'_give_terms_option',
774
775
				// Billing fields.
776
				'_give_offline_donation_enable_billing_fields_single',
777
			);
778
779
			foreach ( $form_radio_settings as $meta_key ) {
780
				// Get value.
781
				$field_value = give_get_meta( get_the_ID(), $meta_key, true );
782
783
				// Convert meta value only if it is in yes/no/none.
784
				if ( in_array( $field_value, array( 'yes', 'on', 'no', 'none' ) ) ) {
785
786
					$field_value = ( in_array( $field_value, array( 'yes', 'on' ) ) ? 'enabled' : 'disabled' );
787
					give_update_meta( get_the_ID(), $meta_key, $field_value );
788
				}
789
			}
790
		}// 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...
791
792
		wp_reset_postdata();
793
794
		// Forms found so upgrade them
795
		$step ++;
796
		$redirect = add_query_arg( array(
797
			'page'         => 'give-upgrades',
798
			'give-upgrade' => 'give_v18_upgrades_form_metadata',
799
			'step'         => $step,
800
		), admin_url( 'index.php' ) );
801
		wp_redirect( $redirect );
802
		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...
803
804
	} else {
805
		// No more forms found, finish up.
806
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
807
		delete_option( 'give_doing_upgrade' );
808
		give_set_upgrade_complete( 'v18_upgrades_form_metadata' );
809
810
		wp_redirect( admin_url() );
811
		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...
812
	}
813
}
814
815
add_action( 'give_give_v18_upgrades_form_metadata', 'give_v18_upgrades_form_metadata' );
816
817
/**
818
 * Get list of core setting renamed in version 1.8.
819
 *
820
 * @since  1.8
821
 * @return array
822
 */
823
function give_v18_renamed_core_settings() {
824
	return array(
825
		'disable_paypal_verification' => 'paypal_verification',
826
		'disable_css'                 => 'css',
827
		'disable_welcome'             => 'welcome',
828
		'disable_forms_singular'      => 'forms_singular',
829
		'disable_forms_archives'      => 'forms_archives',
830
		'disable_forms_excerpt'       => 'forms_excerpt',
831
		'disable_form_featured_img'   => 'form_featured_img',
832
		'disable_form_sidebar'        => 'form_sidebar',
833
		'disable_admin_notices'       => 'admin_notices',
834
		'disable_the_content_filter'  => 'the_content_filter',
835
		'enable_floatlabels'          => 'floatlabels',
836
		'enable_categories'           => 'categories',
837
		'enable_tags'                 => 'tags',
838
	);
839
}
840
841
842
/**
843
 * Upgrade core settings.
844
 *
845
 * @since  1.8.7
846
 * @return void
847
 */
848
function give_v187_upgrades(){
849
	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...
850
851
	/**
852
	 * Upgrade 1: Remove stat and cache transients.
853
	 */
854
	$cached_options = $wpdb->get_col(
855
		$wpdb->prepare(
856
			"SELECT * FROM {$wpdb->options} where (option_name LIKE '%%%s%%' OR option_name LIKE '%%%s%%')",
857
			array(
858
				'_transient_give_stats_',
859
				'give_cache',
860
				'_transient_give_add_ons_feed',
861
				'_transient__give_ajax_works'.
862
				'_transient_give_total_api_keys',
863
				'_transient_give_i18n_give_promo_hide',
864
				'_transient_give_contributors',
865
				'_transient_give_estimated_monthly_stats',
866
				'_transient_give_earnings_total',
867
				'_transient_give_i18n_give_',
868
				'_transient__give_installed',
869
				'_transient__give_activation_redirect',
870
				'_transient__give_hide_license_notices_shortly_',
871
				'give_income_total'
872
			)
873
		),
874
		1
875
	);
876
877
	// User related transients.
878
	$user_apikey_options = $wpdb->get_results(
879
		$wpdb->prepare(
880
			"SELECT user_id, meta_key
881
			FROM $wpdb->usermeta
882
			WHERE meta_value=%s",
883
			'give_user_public_key'
884
		),
885
		ARRAY_A
886
	);
887
888
	if( ! empty( $user_apikey_options ) ) {
889
		foreach ( $user_apikey_options as $user ) {
890
			$cached_options[] = '_transient_' . md5( 'give_api_user_' . $user['meta_key'] );
891
			$cached_options[] = '_transient_' . md5( 'give_api_user_public_key' . $user['user_id'] );
892
			$cached_options[] = '_transient_' . md5( 'give_api_user_secret_key' . $user['user_id'] );
893
		}
894
	}
895
896
	if ( ! empty( $cached_options ) ) {
897
		foreach ( $cached_options as $option ) {
898
			switch ( true ) {
899
				case ( false !== strpos( $option, 'transient' ) ):
900
					$option = str_replace( '_transient_', '', $option );
901
					delete_transient( $option );
902
					break;
903
904
				default:
905
					delete_option( $option );
906
			}
907
		}
908
	}
909
}
910
911
/**
912
 * 2.0 Upgrades.
913
 *
914
 * @since  2.0
915
 * @return void
916
 */
917
function give_v20_upgrades() {
918
	// Upgrade email settings.
919
	give_v20_upgrades_email_setting();
920
}
921
922
/**
923
 * Move old email api settings to new email setting api for following emails:
924
 *    1. new offline donation         [This was hard coded]
925
 *    2. offline donation instruction
926
 *    3. new donation
927
 *    4. donation receipt
928
 *
929
 * @since 2.0
930
 */
931
function give_v20_upgrades_email_setting() {
932
	$all_setting = give_get_settings();
933
934
	// Bailout on fresh install.
935
	if( empty( $all_setting ) ) {
936
		return;
937
	}
938
939
	$settings    = array(
940
		'offline_donation_subject'      => 'offline-donation-instruction_email_subject',
941
		'global_offline_donation_email' => 'offline-donation-instruction_email_message',
942
		'donation_subject'              => 'donation-receipt_email_subject',
943
		'donation_receipt'              => 'donation-receipt_email_message',
944
		'donation_notification_subject' => 'new-donation_email_subject',
945
		'donation_notification'         => 'new-donation_email_message',
946
		'admin_notice_emails'           => array(
947
			'new-donation_recipient',
948
			'new-offline-donation_recipient',
949
			'new-donor-register_recipient',
950
		),
951
		'admin_notices'                 => 'new-donation_notification',
952
	);
953
954
	foreach ( $settings as $old_setting => $new_setting ) {
955
		// Do not update already modified
956
		if( ! is_array( $new_setting ) ) {
957
			if ( array_key_exists( $new_setting, $all_setting ) || ! array_key_exists( $old_setting, $all_setting ) ) {
958
				continue;
959
			}
960
		}
961
962
		switch ( $old_setting ) {
963
			case 'admin_notices':
964
				$notification_status = give_get_option( $old_setting, 'disabled' );
965
966
				give_update_option( $new_setting, $notification_status );
967
				give_delete_option( $old_setting );
968
				break;
969
970
			// @todo: Delete this option later ( version > 2.0 ) because we need this for backward compatibility give_get_admin_notice_emails.
971
			case 'admin_notice_emails':
972
				$recipients = give_get_admin_notice_emails();
0 ignored issues
show
Deprecated Code introduced by
The function give_get_admin_notice_emails() has been deprecated with message: 2.0

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
973
974
				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...
975
					// bailout if setting already exist.
976
					if( array_key_exists( $setting, $all_setting ) ) {
977
						continue;
978
					}
979
980
					give_update_option( $setting, $recipients );
981
				}
982
				break;
983
984
			default:
985
				give_update_option( $new_setting, give_get_option( $old_setting ) );
986
				give_delete_option( $old_setting );
987
		}
988
	}
989
}
990
991
992
/**
993
 * Upgrade form metadata for new metabox settings.
994
 *
995
 * @since  1.8
996
 * @return void
997
 */
998
function give_v20_upgrades_form_metadata() {
999
	if ( ! current_user_can( 'manage_give_settings' ) ) {
1000
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array(
1001
			'response' => 403,
1002
		) );
1003
	}
1004
1005
	ignore_user_abort( true );
1006
1007
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
1008
		@set_time_limit( 0 );
1009
	}
1010
1011
	$step = isset( $_GET['step'] ) ? absint( $_GET['step'] ) : 1;
1012
1013
	// form query
1014
	$forms = new WP_Query( array(
1015
			'paged'          => $step,
1016
			'status'         => 'any',
1017
			'order'          => 'ASC',
1018
			'post_type'      => 'give_forms',
1019
			'posts_per_page' => 20,
1020
		)
1021
	);
1022
1023
	if ( $forms->have_posts() ) {
1024
		while ( $forms->have_posts() ) {
1025
			$forms->the_post();
1026
1027
			// Update offline instruction email notification status.
1028
			$offline_instruction_notification_status = get_post_meta( get_the_ID(), '_give_customize_offline_donations', true );
1029
			$offline_instruction_notification_status = give_is_setting_enabled( $offline_instruction_notification_status, array( 'enabled', 'global' ) )
1030
				? $offline_instruction_notification_status
1031
				: 'global';
1032
			update_post_meta( get_the_ID(), '_give_offline-donation-instruction_notification', $offline_instruction_notification_status );
1033
1034
			// Update offline instruction email message.
1035
			update_post_meta(
1036
				get_the_ID(),
1037
				'_give_offline-donation-instruction_email_message',
1038
				get_post_meta(
1039
					get_the_ID(),
1040
					// @todo: Delete this option later ( version > 2.0 ).
1041
					'_give_offline_donation_email',
1042
					true
1043
				)
1044
			);
1045
1046
			// Update offline instruction email subject.
1047
			update_post_meta(
1048
				get_the_ID(),
1049
				'_give_offline-donation-instruction_email_subject',
1050
				get_post_meta(
1051
					get_the_ID(),
1052
					// @todo: Delete this option later ( version > 2.0 ).
1053
					'_give_offline_donation_subject',
1054
					true
1055
				)
1056
			);
1057
1058
1059
		}// 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...
1060
1061
		wp_reset_postdata();
1062
1063
		// Forms found so upgrade them
1064
		$step ++;
1065
		$redirect = add_query_arg( array(
1066
			'page'         => 'give-upgrades',
1067
			'give-upgrade' => 'give_v20_upgrades_form_metadata',
1068
			'step'         => $step,
1069
		), admin_url( 'index.php' ) );
1070
		wp_redirect( $redirect );
1071
		exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_v20_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...
1072
1073
	} else {
1074
		// No more forms found, finish up.
1075
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
1076
		delete_option( 'give_doing_upgrade' );
1077
		give_set_upgrade_complete( 'v20_upgrades_form_metadata' );
1078
1079
		wp_redirect( admin_url() );
1080
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_v20_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...
1081
	}
1082
}
1083
1084
add_action( 'give_give_v20_upgrades_form_metadata', 'give_v20_upgrades_form_metadata' );