Completed
Pull Request — master (#859)
by Devin
19:40
created

upgrade-functions.php ➔ give_do_automatic_upgrades()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 11
rs 9.4285
ccs 0
cts 6
cp 0
crap 12
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 27 and the first side effect is on line 17.

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     http://opensource.org/licenses/gpl-2.0.php 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
15
// Exit if accessed directly
16
if ( ! defined( 'ABSPATH' ) ) {
17
	exit;
18
}
19
20
21
/**
22
 * Perform automatic database upgrades when necessary
23
 *
24
 * @since 1.6
25
 * @return void
26
 */
27
function give_do_automatic_upgrades() {
28
	$did_upgrade  = false;
29
	$give_version = preg_replace( '/[^0-9.].*/', '', get_option( 'give_version' ) );
30
	if ( version_compare( $give_version, GIVE_VERSION, '<' ) ) {
31
		give_v16_upgrades();
32
		$did_upgrade = true;
33
	}
34
	if ( $did_upgrade ) {
35
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
36
	}
37
}
38
39
add_action( 'admin_init', 'give_do_automatic_upgrades' );
40
41
/**
42
 * Display Upgrade Notices
43
 *
44
 * @since 1.0
45
 * @return void
46
 */
47
function give_show_upgrade_notices() {
48
49
	if ( isset( $_GET['page'] ) && $_GET['page'] == 'give-upgrades' ) {
50
		return;
51
	} // Don't show notices on the upgrades page
52
53
	$give_version = get_option( 'give_version' );
54
55
	if ( ! $give_version ) {
56
		// 1.0 is the first version to use this option so we must add it
57
		$give_version = '1.0';
58
	}
59
60
	$give_version = preg_replace( '/[^0-9.].*/', '', $give_version );
61
62
	/*
63
	 *  NOTICE:
64
	 *
65
	 *  When adding new upgrade notices, please be sure to put the action into the upgrades array during install:
66
	 *  /includes/install.php @ Appox Line 156
67
	 *
68
	 */
69
70
	//v1.3.2 Upgrades
71
	if ( version_compare( $give_version, '1.3.2', '<' ) || ! give_has_upgrade_completed( 'upgrade_give_payment_customer_id' ) ) {
72
		printf(
73
		/* translators: %s: upgrade URL */
74
			'<div class="updated"><p>' . __( 'Give needs to upgrade the donor database, click <a href="%s">here</a> to start the upgrade.', 'give' ) . '</p></div>',
75
			esc_url( admin_url( 'index.php?page=give-upgrades&give-upgrade=upgrade_give_payment_customer_id' ) )
76
		);
77
	}
78
79
	//v1.3.4 Upgrades //ensure the user has gone through 1.3.4
80
	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' ) ) ) {
81
		printf(
82
		/* translators: %s: upgrade URL */
83
			'<div class="updated"><p>' . __( 'Give needs to upgrade the transaction database, click <a href="%s">here</a> to start the upgrade.', 'give' ) . '</p></div>',
84
			esc_url( admin_url( 'index.php?page=give-upgrades&give-upgrade=upgrade_give_offline_status' ) )
85
		);
86
	}
87
88
89
	// End 'Stepped' upgrade process notices
90
91
92
}
93
94
add_action( 'admin_notices', 'give_show_upgrade_notices' );
95
96
/**
97
 * Triggers all upgrade functions
98
 *
99
 * This function is usually triggered via AJAX
100
 *
101
 * @since 1.0
102
 * @return void
103
 */
104
function give_trigger_upgrades() {
105
106
	if ( ! current_user_can( 'manage_give_settings' ) ) {
107
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
108
	}
109
110
	$give_version = get_option( 'give_version' );
111
112
	if ( ! $give_version ) {
113
		// 1.0 is the first version to use this option so we must add it
114
		$give_version = '1.0';
115
		add_option( 'give_version', $give_version );
116
	}
117 1
118
	update_option( 'give_version', GIVE_VERSION );
119
120
	if ( DOING_AJAX ) {
121 1
		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...
122
	} // Let AJAX know that the upgrade is complete
123 1
}
124
125
add_action( 'wp_ajax_give_trigger_upgrades', 'give_trigger_upgrades' );
126
127
/**
128
 * Check if the upgrade routine has been run for a specific action
129
 *
130
 * @since  1.0
131
 *
132
 * @param  string $upgrade_action The upgrade action to check completion for
133
 *
134
 * @return bool                   If the action has been added to the completed actions array
135
 */
136
function give_has_upgrade_completed( $upgrade_action = '' ) {
137
138 1
	if ( empty( $upgrade_action ) ) {
139
		return false;
140
	}
141
142 1
	$completed_upgrades = give_get_completed_upgrades();
143 1
144
	return in_array( $upgrade_action, $completed_upgrades );
145
146 1
}
147
148 1
/**
149
 * Adds an upgrade action to the completed upgrades array
150
 *
151
 * @since  1.0
152
 *
153
 * @param  string $upgrade_action The action to add to the completed upgrades array
154
 *
155
 * @return bool                   If the function was successfully added
156
 */
157
function give_set_upgrade_complete( $upgrade_action = '' ) {
158
159 1
	if ( empty( $upgrade_action ) ) {
160
		return false;
161 1
	}
162
163
	$completed_upgrades   = give_get_completed_upgrades();
164
	$completed_upgrades[] = $upgrade_action;
165 1
166
	// Remove any blanks, and only show uniques
167
	$completed_upgrades = array_unique( array_values( $completed_upgrades ) );
168
169
	return update_option( 'give_completed_upgrades', $completed_upgrades );
170
}
171
172
/**
173
 * Get's the array of completed upgrade actions
174
 *
175
 * @since  1.0
176
 * @return array The array of completed upgrades
177
 */
178
function give_get_completed_upgrades() {
179
180
	$completed_upgrades = get_option( 'give_completed_upgrades' );
181
182
	if ( false === $completed_upgrades ) {
183
		$completed_upgrades = array();
184
	}
185
186
	return $completed_upgrades;
187
188
}
189
190
/**
191
 * Upgrades the
192
 *
193
 * Standardizes the discrepancies between two metakeys `_give_payment_customer_id` and `_give_payment_donor_id`
194
 *
195
 * @since      1.3.2
196
 *
197
 */
198
function give_v132_upgrade_give_payment_customer_id() {
199
	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...
200
	if ( ! current_user_can( 'manage_give_settings' ) ) {
201
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
202
	}
203
204
	ignore_user_abort( true );
205
206
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
207
		@set_time_limit( 0 );
208
	}
209
210
	//UPDATE DB METAKEYS
211
	$sql   = "UPDATE $wpdb->postmeta SET meta_key = '_give_payment_customer_id' WHERE meta_key = '_give_payment_donor_id'";
212
	$query = $wpdb->query( $sql );
213
214
	update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
215
	give_set_upgrade_complete( 'upgrade_give_payment_customer_id' );
216
	delete_option( 'give_doing_upgrade' );
217
	wp_redirect( admin_url() );
218
	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...
219
220
221
}
222
223
add_action( 'give_upgrade_give_payment_customer_id', 'give_v132_upgrade_give_payment_customer_id' );
224
225
/**
226
 * Upgrades the Offline Status
227
 *
228
 * Reverses the issue where offline donation transactions in "pending" status where inappropriately marked as abandoned
229
 *
230
 * @since      1.3.4
231
 *
232
 */
233
function give_v134_upgrade_give_offline_status() {
234
235
	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...
236
237
	if ( ! current_user_can( 'manage_give_settings' ) ) {
238
		wp_die( esc_html__( 'You do not have permission to do Give upgrades.', 'give' ), esc_html__( 'Error', 'give' ), array( 'response' => 403 ) );
239
	}
240
241
	ignore_user_abort( true );
242
243
	if ( ! give_is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) {
244
		@set_time_limit( 0 );
245
	}
246
247
	// Get abandoned offline payments
248
	$select = "SELECT ID FROM $wpdb->posts p ";
249
	$join   = "LEFT JOIN $wpdb->postmeta m ON p.ID = m.post_id ";
250
	$where  = "WHERE p.post_type = 'give_payment' ";
251
	$where .= "AND ( p.post_status = 'abandoned' )";
252
	$where .= "AND ( m.meta_key = '_give_payment_gateway' AND m.meta_value = 'offline' )";
253
254
	$sql            = $select . $join . $where;
255
	$found_payments = $wpdb->get_col( $sql );
256
257
258
	foreach ( $found_payments as $payment ) {
259
260
		//Only change ones marked abandoned since our release last week
261
		//because the admin may have marked some abandoned themselves
262
		$modified_time = get_post_modified_time( 'U', false, $payment );
263
264
		//1450124863 =  12/10/2015 20:42:25
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% 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...
265
		if ( $modified_time >= 1450124863 ) {
266
267
			give_update_payment_status( $payment, 'pending' );
268
269
		}
270
271
	}
272
273
	update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
274
	give_set_upgrade_complete( 'upgrade_give_offline_status' );
275
	delete_option( 'give_doing_upgrade' );
276
	wp_redirect( admin_url() );
277
	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...
278
279
280
}
281
282
add_action( 'give_upgrade_give_offline_status', 'give_v134_upgrade_give_offline_status' );
283
284
/**
285
 * Cleanup User Roles
286
 *
287
 * This upgrade routine removes unused roles and roles with typos
288
 *
289
 * @since      1.5.2
290
 */
291
function give_v152_cleanup_users() {
292
293
	$give_version = get_option( 'give_version' );
294
295
	if ( ! $give_version ) {
296
		// 1.0 is the first version to use this option so we must add it
297
		$give_version = '1.0';
298
	}
299
300
	$give_version = preg_replace( '/[^0-9.].*/', '', $give_version );
301
302
	//v1.5.2 Upgrades
303
	if ( version_compare( $give_version, '1.5.2', '<' ) || ! give_has_upgrade_completed( 'upgrade_give_user_caps_cleanup' ) ) {
304
305
		//Delete all caps with "ss"
306
		//Also delete all unused "campaign" roles
307
		$delete_caps = array(
308
			'delete_give_formss',
309
			'delete_others_give_formss',
310
			'delete_private_give_formss',
311
			'delete_published_give_formss',
312
			'read_private_forms',
313
			'edit_give_formss',
314
			'edit_others_give_formss',
315
			'edit_private_give_formss',
316
			'edit_published_give_formss',
317
			'publish_give_formss',
318
			'read_private_give_formss',
319
			'assign_give_campaigns_terms',
320
			'delete_give_campaigns',
321
			'delete_give_campaigns_terms',
322
			'delete_give_campaignss',
323
			'delete_others_give_campaignss',
324
			'delete_private_give_campaignss',
325
			'delete_published_give_campaignss',
326
			'edit_give_campaigns',
327
			'edit_give_campaigns_terms',
328
			'edit_give_campaignss',
329
			'edit_others_give_campaignss',
330
			'edit_private_give_campaignss',
331
			'edit_published_give_campaignss',
332
			'manage_give_campaigns_terms',
333
			'publish_give_campaignss',
334
			'read_give_campaigns',
335
			'read_private_give_campaignss',
336
			'view_give_campaigns_stats',
337
			'delete_give_paymentss',
338
			'delete_others_give_paymentss',
339
			'delete_private_give_paymentss',
340
			'delete_published_give_paymentss',
341
			'edit_give_paymentss',
342
			'edit_others_give_paymentss',
343
			'edit_private_give_paymentss',
344
			'edit_published_give_paymentss',
345
			'publish_give_paymentss',
346
			'read_private_give_paymentss',
347
		);
348
349
		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...
350
		foreach ( $delete_caps as $cap ) {
351
			foreach ( array_keys( $wp_roles->roles ) as $role ) {
352
				$wp_roles->remove_cap( $role, $cap );
353
			}
354
		}
355
356
		// Create Give plugin roles
357
		$roles = new Give_Roles();
358
		$roles->add_roles();
359
		$roles->add_caps();
360
361
		//The Update Ran
362
		update_option( 'give_version', preg_replace( '/[^0-9.].*/', '', GIVE_VERSION ) );
363
		give_set_upgrade_complete( 'upgrade_give_user_caps_cleanup' );
364
		delete_option( 'give_doing_upgrade' );
365
366
	}
367
368
}
369
370
add_action( 'admin_init', 'give_v152_cleanup_users' );
371
372
/**
373
 * 1.6 Upgrade routine to create the customer meta table.
374
 *
375
 * @since  1.6
376
 * @return void
377
 */
378
function give_v16_upgrades() {
379
	@Give()->customers->create_table();
380
	@Give()->customer_meta->create_table();
381
}