Completed
Push — issues/1132 ( 73d4a7...a02540 )
by Ravinder
18:52
created

donor-actions.php ➔ give_edit_donor()   F

Complexity

Conditions 31
Paths 15506

Size

Total Lines 154
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 31
eloc 75
nc 15506
nop 1
dl 0
loc 154
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
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 14.

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
 * Donors
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Donors
7
 * @copyright   Copyright (c) 2016, WordImpress
8
 * @license     https://opensource.org/licenses/gpl-license GNU Public License
9
 * @since       1.0
10
 */
11
12
// Exit if accessed directly.
13
if ( ! defined( 'ABSPATH' ) ) {
14
	exit;
15
}
16
17
/**
18
 * Processes a donor edit.
19
 *
20
 * @since  1.0
21
 *
22
 * @param  array $args The $_POST array being passed
23
 *
24
 * @return array|bool $output Response messages
25
 */
26
function give_edit_donor( $args ) {
27
28
	$donor_edit_role = apply_filters( 'give_edit_donors_role', 'edit_give_payments' );
29
30
	if ( ! is_admin() || ! current_user_can( $donor_edit_role ) ) {
31
		wp_die( __( 'You do not have permission to edit this donor.', 'give' ), __( 'Error', 'give' ), array(
32
			'response' => 403,
33
		) );
34
	}
35
36
	if ( empty( $args ) ) {
37
		return false;
38
	}
39
40
	$donor_info = $args['customerinfo'];
41
	$donor_id   = (int) $args['customerinfo']['id'];
42
	$nonce      = $args['_wpnonce'];
43
44
	if ( ! wp_verify_nonce( $nonce, 'edit-donor' ) ) {
45
		wp_die( __( 'Cheatin&#8217; uh?', 'give' ), __( 'Error', 'give' ), array(
46
			'response' => 400,
47
		) );
48
	}
49
50
	$donor = new Give_Donor( $donor_id );
51
52
	if ( empty( $donor->id ) ) {
53
		return false;
54
	}
55
56
	$defaults = array(
57
		'name'    => '',
58
		'user_id' => 0,
59
	);
60
61
	$donor_info = wp_parse_args( $donor_info, $defaults );
62
63
	if ( (int) $donor_info['user_id'] !== (int) $donor->user_id ) {
64
65
		// Make sure we don't already have this user attached to a donor.
66
		if ( ! empty( $donor_info['user_id'] ) && false !== Give()->donors->get_donor_by( 'user_id', $donor_info['user_id'] ) ) {
67
			give_set_error( 'give-invalid-donor-user_id', sprintf( __( 'The User ID #%d is already associated with a different donor.', 'give' ), $donor_info['user_id'] ) );
68
		}
69
70
		// Make sure it's actually a user.
71
		$user = get_user_by( 'id', $donor_info['user_id'] );
72
		if ( ! empty( $donor_info['user_id'] ) && false === $user ) {
73
			give_set_error( 'give-invalid-user_id', sprintf( __( 'The User ID #%d does not exist. Please assign an existing user.', 'give' ), $donor_info['user_id'] ) );
74
		}
75
	}
76
77
	// Record this for later.
78
	$previous_user_id = $donor->user_id;
79
80
	if ( give_get_errors() ) {
81
		return false;
82
	}
83
84
	// Setup the donor address, if present.
85
	$address = array();
86
	if ( intval( $donor_info['user_id'] ) > 0 ) {
87
88
		$current_address = get_user_meta( $donor_info['user_id'], '_give_user_address', true );
89
90
		if ( false === $current_address ) {
91
			$address['line1']   = isset( $donor_info['line1'] ) ? $donor_info['line1'] : '';
92
			$address['line2']   = isset( $donor_info['line2'] ) ? $donor_info['line2'] : '';
93
			$address['city']    = isset( $donor_info['city'] ) ? $donor_info['city'] : '';
94
			$address['country'] = isset( $donor_info['country'] ) ? $donor_info['country'] : '';
95
			$address['zip']     = isset( $donor_info['zip'] ) ? $donor_info['zip'] : '';
96
			$address['state']   = isset( $donor_info['state'] ) ? $donor_info['state'] : '';
97
		} else {
98
			$current_address    = wp_parse_args( $current_address, array(
99
				'line1',
100
				'line2',
101
				'city',
102
				'zip',
103
				'state',
104
				'country',
105
			) );
106
			$address['line1']   = isset( $donor_info['line1'] ) ? $donor_info['line1'] : $current_address['line1'];
107
			$address['line2']   = isset( $donor_info['line2'] ) ? $donor_info['line2'] : $current_address['line2'];
108
			$address['city']    = isset( $donor_info['city'] ) ? $donor_info['city'] : $current_address['city'];
109
			$address['country'] = isset( $donor_info['country'] ) ? $donor_info['country'] : $current_address['country'];
110
			$address['zip']     = isset( $donor_info['zip'] ) ? $donor_info['zip'] : $current_address['zip'];
111
			$address['state']   = isset( $donor_info['state'] ) ? $donor_info['state'] : $current_address['state'];
112
		}
113
	}
114
115
	// Sanitize the inputs
116
	$donor_data            = array();
117
	$donor_data['name']    = strip_tags( stripslashes( $donor_info['name'] ) );
118
	$donor_data['user_id'] = $donor_info['user_id'];
119
120
	$donor_data = apply_filters( 'give_edit_donor_info', $donor_data, $donor_id );
121
	$address    = apply_filters( 'give_edit_donor_address', $address, $donor_id );
122
123
	$donor_data = array_map( 'sanitize_text_field', $donor_data );
124
	$address    = array_map( 'sanitize_text_field', $address );
125
126
	/**
127
	 * Fires before editing a donor.
128
	 *
129
	 * @since 1.0
130
	 *
131
	 * @param int   $donor_id   The ID of the donor.
132
	 * @param array $donor_data The donor data.
133
	 * @param array $address    The donor's address.
134
	 */
135
	do_action( 'give_pre_edit_donor', $donor_id, $donor_data, $address );
136
137
	$output = array();
138
139
	$output['success'] = false;
140
	if ( $donor->update( $donor_data ) ) {
141
142
		if ( ! empty( $donor->user_id ) && $donor->user_id > 0 ) {
143
			update_user_meta( $donor->user_id, '_give_user_address', $address );
144
		}
145
146
		// Update some donation meta if we need to.
147
		// $payments_array = explode( ',', $donor->payment_ids );
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
148
		//
149
		// if ( $donor->user_id != $previous_user_id ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
48% 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...
150
		// 	foreach ( $payments_array as $payment_id ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
151
		// 		give_update_payment_meta( $payment_id, '_give_payment_user_id', $donor->user_id );
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...
152
		// 	}
153
		// }
154
155
		$output['success']       = true;
156
		$donor_data              = array_merge( $donor_data, $address );
157
		$output['customer_info'] = $donor_data;
158
159
	}
160
161
	/**
162
	 * Fires after editing a donor.
163
	 *
164
	 * @since 1.0
165
	 *
166
	 * @param int   $donor_id   The ID of the donor.
167
	 * @param array $donor_data The donor data.
168
	 */
169
	do_action( 'give_post_edit_donor', $donor_id, $donor_data );
170
171
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
172
		header( 'Content-Type: application/json' );
173
		echo json_encode( $output );
174
		wp_die();
175
	}
176
177
	return $output;
178
179
}
180
181
add_action( 'give_edit-donor', 'give_edit_donor', 10, 1 );
182
183
/**
184
 * Save a donor note.
185
 *
186
 * @since  1.0
187
 *
188
 * @param  array $args The $_POST array being passed.
189
 *
190
 * @return int         The Note ID that was saved, or 0 if nothing was saved.
0 ignored issues
show
Documentation introduced by
Should the return type not be null|string|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
191
 */
192
function give_donor_save_note( $args ) {
193
194
	$donor_view_role = apply_filters( 'give_view_donors_role', 'view_give_reports' );
195
196
	if ( ! is_admin() || ! current_user_can( $donor_view_role ) ) {
197
		wp_die( __( 'You do not have permission to edit this donor.', 'give' ), __( 'Error', 'give' ), array(
198
			'response' => 403,
199
		) );
200
	}
201
202
	if ( empty( $args ) ) {
203
		return false;
204
	}
205
206
	$donor_note = trim( sanitize_text_field( $args['donor_note'] ) );
207
	$donor_id   = (int) $args['customer_id'];
208
	$nonce      = $args['add_donor_note_nonce'];
209
210
	if ( ! wp_verify_nonce( $nonce, 'add-donor-note' ) ) {
211
		wp_die( __( 'Cheatin&#8217; uh?', 'give' ), __( 'Error', 'give' ), array(
212
			'response' => 400,
213
		) );
214
	}
215
216
	if ( empty( $donor_note ) ) {
217
		give_set_error( 'empty-donor-note', __( 'A note is required.', 'give' ) );
218
	}
219
220
	if ( give_get_errors() ) {
221
		return false;
222
	}
223
224
	$donor    = new Give_Donor( $donor_id );
225
	$new_note = $donor->add_note( $donor_note );
226
227
	/**
228
	 * Fires before inserting donor note.
229
	 *
230
	 * @since 1.0
231
	 *
232
	 * @param int    $donor_id The ID of the donor.
233
	 * @param string $new_note Note content.
234
	 */
235
	do_action( 'give_pre_insert_donor_note', $donor_id, $new_note );
236
237
	if ( ! empty( $new_note ) && ! empty( $donor->id ) ) {
238
239
		ob_start();
240
		?>
241
		<div class="donor-note-wrapper dashboard-comment-wrap comment-item">
242
			<span class="note-content-wrap">
243
				<?php echo stripslashes( $new_note ); ?>
244
			</span>
245
		</div>
246
		<?php
247
		$output = ob_get_contents();
248
		ob_end_clean();
249
250
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
251
			echo $output;
252
			exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_donor_save_note() 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...
253
		}
254
255
		return $new_note;
256
257
	}
258
259
	return false;
260
261
}
262
263
add_action( 'give_add-donor-note', 'give_donor_save_note', 10, 1 );
264
265
/**
266
 * Delete a donor.
267
 *
268
 * @since  1.0
269
 *
270
 * @param  array $args The $_POST array being passed.
271
 *
272
 * @return int Whether it was a successful deletion.
0 ignored issues
show
Documentation introduced by
Should the return type not be false|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
273
 */
274
function give_donor_delete( $args ) {
275
276
	$donor_edit_role = apply_filters( 'give_edit_donors_role', 'edit_give_payments' );
277
278
	if ( ! is_admin() || ! current_user_can( $donor_edit_role ) ) {
279
		wp_die( __( 'You do not have permission to delete donors.', 'give' ), __( 'Error', 'give' ), array(
280
			'response' => 403,
281
		) );
282
	}
283
284
	if ( empty( $args ) ) {
285
		return false;
286
	}
287
288
	$donor_id    = (int) $args['customer_id'];
289
	$confirm     = ! empty( $args['give-donor-delete-confirm'] ) ? true : false;
290
	$remove_data = ! empty( $args['give-donor-delete-records'] ) ? true : false;
291
	$nonce       = $args['_wpnonce'];
292
293
	if ( ! wp_verify_nonce( $nonce, 'delete-donor' ) ) {
294
		wp_die( __( 'Cheatin&#8217; uh?', 'give' ), __( 'Error', 'give' ), array(
295
			'response' => 400,
296
		) );
297
	}
298
299
	if ( ! $confirm ) {
300
		give_set_error( 'donor-delete-no-confirm', __( 'Please confirm you want to delete this donor.', 'give' ) );
301
	}
302
303
	if ( give_get_errors() ) {
304
		wp_redirect( admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor_id ) );
305
		exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_donor_delete() 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...
306
	}
307
308
	$donor = new Give_Donor( $donor_id );
309
310
	/**
311
	 * Fires before deleting donor.
312
	 *
313
	 * @since 1.0
314
	 *
315
	 * @param int  $donor_id    The ID of the donor.
316
	 * @param bool $confirm     Delete confirmation.
317
	 * @param bool $remove_data Records delete confirmation.
318
	 */
319
	do_action( 'give_pre_delete_donor', $donor_id, $confirm, $remove_data );
320
321
	if ( $donor->id > 0 ) {
322
323
		$payments_array = explode( ',', $donor->payment_ids );
324
		$success        = Give()->donors->delete( $donor->id );
325
326
		if ( $success ) {
327
328
			if ( $remove_data ) {
329
330
				// Remove all donations, logs, etc
331
				foreach ( $payments_array as $payment_id ) {
332
					give_delete_donation( $payment_id );
333
				}
334
			} else {
335
336
				// Just set the donations to customer_id of 0
337
				foreach ( $payments_array as $payment_id ) {
338
					give_update_payment_meta( $payment_id, '_give_payment_donor_id', 0 );
339
				}
340
			}
341
342
			$redirect = admin_url( 'edit.php?post_type=give_forms&page=give-donors&give-message=donor-deleted' );
343
344
		} else {
345
346
			give_set_error( 'give-donor-delete-failed', esc_html__( 'Error deleting donor.', 'give' ) );
347
			$redirect = admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=delete&id=' . $donor_id );
348
349
		}
350
	} else {
351
352
		give_set_error( 'give-donor-delete-invalid-id', esc_html__( 'Invalid Donor ID.', 'give' ) );
353
		$redirect = admin_url( 'edit.php?post_type=give_forms&page=give-donors' );
354
355
	}
356
357
	wp_redirect( $redirect );
358
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_donor_delete() 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...
359
360
}
361
362
add_action( 'give_delete-donor', 'give_donor_delete', 10, 1 );
363
364
/**
365
 * Disconnect a user ID from a donor
366
 *
367
 * @since  1.0
368
 *
369
 * @param  array $args Array of arguments.
370
 *
371
 * @return bool|array        If the disconnect was successful.
372
 */
373
function give_disconnect_donor_user_id( $args ) {
374
375
	$donor_edit_role = apply_filters( 'give_edit_donors_role', 'edit_give_payments' );
376
377
	if ( ! is_admin() || ! current_user_can( $donor_edit_role ) ) {
378
		wp_die( __( 'You do not have permission to edit this donor.', 'give' ), __( 'Error', 'give' ), array(
379
			'response' => 403,
380
		) );
381
	}
382
383
	if ( empty( $args ) ) {
384
		return false;
385
	}
386
387
	$donor_id = (int) $args['customer_id'];
388
389
	$nonce = $args['_wpnonce'];
390
391
	if ( ! wp_verify_nonce( $nonce, 'edit-donor' ) ) {
392
		wp_die( __( 'Cheatin&#8217; uh?', 'give' ), __( 'Error', 'give' ), array(
393
			'response' => 400,
394
		) );
395
	}
396
397
	$donor = new Give_Donor( $donor_id );
398
	if ( empty( $donor->id ) ) {
399
		return false;
400
	}
401
402
	$user_id = $donor->user_id;
403
404
	/**
405
	 * Fires before disconnecting user ID from a donor.
406
	 *
407
	 * @since 1.0
408
	 *
409
	 * @param int $donor_id The ID of the donor.
410
	 * @param int $user_id  The ID of the user.
411
	 */
412
	do_action( 'give_pre_donor_disconnect_user_id', $donor_id, $user_id );
413
414
	$output     = array();
415
	$donor_args = array(
416
		'user_id' => 0,
417
	);
418
419
420
	$output['success'] = true;
421
	if ( ! $donor->update( $donor_args ) ) {
422
		// if ( $donor->update( $donor_args ) ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% 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...
423
		// 	global $wpdb;
424
		//
425
		// 	if ( ! empty( $donor->payment_ids ) ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
53% 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...
426
		// 		$wpdb->query( "UPDATE $wpdb->postmeta SET meta_value = 0 WHERE meta_key = '_give_payment_user_id' AND post_id IN ( $donor->payment_ids )" );
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...
427
		// 	}
428
		//
429
		// 	$output['success'] = true;
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...
430
		//
431
		// } else {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
432
433
		$output['success'] = false;
434
		give_set_error( 'give-disconnect-user-fail', __( 'Failed to disconnect user from donor.', 'give' ) );
435
	}
436
437
	/**
438
	 * Fires after disconnecting user ID from a donor.
439
	 *
440
	 * @since 1.0
441
	 *
442
	 * @param int $donor_id The ID of the donor.
443
	 */
444
	do_action( 'give_post_donor_disconnect_user_id', $donor_id );
445
446
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
447
		header( 'Content-Type: application/json' );
448
		echo json_encode( $output );
449
		wp_die();
450
	}
451
452
	return $output;
453
454
}
455
456
add_action( 'give_disconnect-userid', 'give_disconnect_donor_user_id', 10, 1 );
457
458
/**
459
 * Add an email address to the donor from within the admin and log a donor note.
460
 *
461
 * @since  1.7
462
 *
463
 * @param  array $args Array of arguments: nonce, donor id, and email address.
464
 *
465
 * @return mixed        If DOING_AJAX echos out JSON, otherwise returns array of success (bool) and message (string).
466
 */
467
function give_add_donor_email( $args ) {
468
	$donor_edit_role = apply_filters( 'give_edit_donors_role', 'edit_give_payments' );
469
470
	if ( ! is_admin() || ! current_user_can( $donor_edit_role ) ) {
471
		wp_die( __( 'You do not have permission to edit this donor.', 'edit' ) );
472
	}
473
474
	$output = array();
475
	if ( empty( $args ) || empty( $args['email'] ) || empty( $args['customer_id'] ) ) {
476
		$output['success'] = false;
477
		if ( empty( $args['email'] ) ) {
478
			$output['message'] = __( 'Email address is required.', 'give' );
479
		} elseif ( empty( $args['customer_id'] ) ) {
480
			$output['message'] = __( 'Donor ID is required.', 'give' );
481
		} else {
482
			$output['message'] = __( 'An error has occurred. Please try again.', 'give' );
483
		}
484
	} elseif ( ! wp_verify_nonce( $args['_wpnonce'], 'give_add_donor_email' ) ) {
485
		$output = array(
486
			'success' => false,
487
			'message' => esc_html__( 'Nonce verification failed.', 'give' ),
488
		);
489
	} elseif ( ! is_email( $args['email'] ) ) {
490
		$output = array(
491
			'success' => false,
492
			'message' => esc_html__( 'Invalid email.', 'give' ),
493
		);
494
	} else {
495
		$email    = sanitize_email( $args['email'] );
496
		$donor_id = (int) $args['customer_id'];
497
		$primary  = 'true' === $args['primary'] ? true : false;
498
		$donor    = new Give_Donor( $donor_id );
499
		if ( false === $donor->add_email( $email, $primary ) ) {
500
			if ( in_array( $email, $donor->emails ) ) {
501
				$output = array(
502
					'success' => false,
503
					'message' => __( 'Email already associated with this donor.', 'give' ),
504
				);
505
			} else {
506
				$output = array(
507
					'success' => false,
508
					'message' => __( 'Email address is already associated with another donor.', 'give' ),
509
				);
510
			}
511
		} else {
512
			$redirect = admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor_id . '&give-message=email-added' );
513
			$output   = array(
514
				'success'  => true,
515
				'message'  => __( 'Email successfully added to donor.', 'give' ),
516
				'redirect' => $redirect,
517
			);
518
519
			$user       = wp_get_current_user();
520
			$user_login = ! empty( $user->user_login ) ? $user->user_login : __( 'System', 'give' );
521
			$donor_note = sprintf( __( 'Email address %1$s added by %2$s', 'give' ), $email, $user_login );
522
			$donor->add_note( $donor_note );
523
524
			if ( $primary ) {
525
				$donor_note = sprintf( __( 'Email address %1$s set as primary by %2$s', 'give' ), $email, $user_login );
526
				$donor->add_note( $donor_note );
527
			}
528
		}
529
	}// 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...
530
531
	do_action( 'give_post_add_donor_email', $donor_id, $args );
0 ignored issues
show
Bug introduced by
The variable $donor_id does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
532
533
	if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
534
		header( 'Content-Type: application/json' );
535
		echo json_encode( $output );
536
		wp_die();
537
	}
538
539
	return $output;
540
}
541
542
add_action( 'give_add_donor_email', 'give_add_donor_email', 10, 1 );
543
544
545
/**
546
 * Remove an email address to the donor from within the admin and log a donor note and redirect back to the donor interface for feedback.
547
 *
548
 * @since  1.7
549
 * @return bool|null
550
 */
551
function give_remove_donor_email() {
552
	if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
553
		return false;
554
	}
555
	if ( empty( $_GET['email'] ) || ! is_email( $_GET['email'] ) ) {
556
		return false;
557
	}
558
	if ( empty( $_GET['_wpnonce'] ) ) {
559
		return false;
560
	}
561
562
	$nonce = $_GET['_wpnonce'];
563
	if ( ! wp_verify_nonce( $nonce, 'give-remove-donor-email' ) ) {
564
		wp_die( esc_html__( 'Nonce verification failed', 'give' ), esc_html__( 'Error', 'give' ), array(
565
			'response' => 403,
566
		) );
567
	}
568
569
	$donor = new Give_Donor( $_GET['id'] );
570
	if ( $donor->remove_email( $_GET['email'] ) ) {
571
		$url        = add_query_arg( 'give-message', 'email-removed', admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ) );
572
		$user       = wp_get_current_user();
573
		$user_login = ! empty( $user->user_login ) ? $user->user_login : __( 'System', 'give' );
574
		$donor_note = sprintf( __( 'Email address %1$s removed by %2$s', 'give' ), $_GET['email'], $user_login );
575
		$donor->add_note( $donor_note );
576
	} else {
577
		$url = add_query_arg( 'give-message', 'email-remove-failed', admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ) );
578
	}
579
580
	wp_safe_redirect( $url );
581
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_remove_donor_email() 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...
582
}
583
584
add_action( 'give_remove_donor_email', 'give_remove_donor_email', 10 );
585
586
587
/**
588
 * Set an email address as the primary for a donor from within the admin and log a donor note
589
 * and redirect back to the donor interface for feedback
590
 *
591
 * @since  1.7
592
 * @return bool|null
593
 */
594
function give_set_donor_primary_email() {
595
	if ( empty( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
596
		return false;
597
	}
598
599
	if ( empty( $_GET['email'] ) || ! is_email( $_GET['email'] ) ) {
600
		return false;
601
	}
602
603
	if ( empty( $_GET['_wpnonce'] ) ) {
604
		return false;
605
	}
606
607
	$nonce = $_GET['_wpnonce'];
608
609
	if ( ! wp_verify_nonce( $nonce, 'give-set-donor-primary-email' ) ) {
610
		wp_die( esc_html__( 'Nonce verification failed', 'give' ), esc_html__( 'Error', 'give' ), array(
611
			'response' => 403,
612
		) );
613
	}
614
615
	$donor = new Give_Donor( $_GET['id'] );
616
617
	if ( $donor->set_primary_email( $_GET['email'] ) ) {
618
		$url        = add_query_arg( 'give-message', 'primary-email-updated', admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ) );
619
		$user       = wp_get_current_user();
620
		$user_login = ! empty( $user->user_login ) ? $user->user_login : esc_html__( 'System', 'give' );
621
		$donor_note = sprintf( __( 'Email address %1$s set as primary by %2$s', 'give' ), $_GET['email'], $user_login );
622
623
		$donor->add_note( $donor_note );
624
	} else {
625
		$url = add_query_arg( 'give-message', 'primary-email-failed', admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ) );
626
	}
627
628
	wp_safe_redirect( $url );
629
	exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The function give_set_donor_primary_email() 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...
630
}
631
632
add_action( 'give_set_donor_primary_email', 'give_set_donor_primary_email', 10 );
633