Issues (4296)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/admin/admin-actions.php (96 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Admin Actions
4
 *
5
 * @package     Give
6
 * @subpackage  Admin/Actions
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
 * Load wp editor by ajax.
19
 *
20
 * @since 1.8
21
 */
22
function give_load_wp_editor() {
23
	if ( ! isset( $_POST['wp_editor'] ) ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
24
		die();
25
	}
26
27
	$wp_editor                     = json_decode( base64_decode( $_POST['wp_editor'] ), true );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
28
	$wp_editor[2]['textarea_name'] = $_POST['textarea_name'];
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
29
30
	wp_editor( $wp_editor[0], $_POST['wp_editor_id'], $wp_editor[2] );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
31
32
	die();
33
}
34
35
add_action( 'wp_ajax_give_load_wp_editor', 'give_load_wp_editor' );
36
37
38
/**
39
 * Redirect admin to clean url give admin pages.
40
 *
41
 * @since 1.8
42
 *
43
 * @return bool
44
 */
45
function give_redirect_to_clean_url_admin_pages() {
46
	// Give admin pages.
47
	$give_pages = array(
48
		'give-payment-history',
49
		'give-donors',
50
		'give-reports',
51
		'give-tools',
52
	);
53
54
	// Get current page.
55
	$current_page = isset( $_GET['page'] ) ? esc_attr( $_GET['page'] ) : '';
0 ignored issues
show
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
56
57
	// Bailout.
58
	if (
59
		empty( $current_page )
60
		|| empty( $_GET['_wp_http_referer'] )
0 ignored issues
show
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
61
		|| ! in_array( $current_page, $give_pages )
62
	) {
63
		return false;
64
	}
65
66
	/**
67
	 * Verify current page request.
68
	 *
69
	 * @since 1.8
70
	 */
71
	$redirect = apply_filters( "give_validate_{$current_page}", true );
72
73
	if ( $redirect ) {
74
		// Redirect.
75
		wp_redirect(
76
			remove_query_arg(
77
				array( '_wp_http_referer', '_wpnonce' ),
78
				wp_unslash( $_SERVER['REQUEST_URI'] )
0 ignored issues
show
Detected usage of a non-validated input variable: $_SERVER
Loading history...
Detected usage of a non-sanitized input variable: $_SERVER
Loading history...
79
			)
80
		);
81
		exit;
82
	}
83
}
84
85
add_action( 'admin_init', 'give_redirect_to_clean_url_admin_pages' );
86
87
88
/**
89
 * Hide Outdated PHP Notice Shortly.
90
 *
91
 * This code is used with AJAX call to hide outdated PHP notice for a short period of time
92
 *
93
 * @since 1.8.9
94
 *
95
 * @return void
96
 */
97
function give_hide_outdated_php_notice() {
98
99
	if ( ! isset( $_POST['_give_hide_outdated_php_notices_shortly'] ) ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
100
		give_die();
101
	}
102
103
	// Transient key name.
104
	$transient_key = '_give_hide_outdated_php_notices_shortly';
105
106
	if ( Give_Cache::get( $transient_key, true ) ) {
107
		return;
108
	}
109
110
	// Hide notice for 24 hours.
111
	Give_Cache::set( $transient_key, true, DAY_IN_SECONDS, true );
112
113
	give_die();
114
115
}
116
117
add_action( 'wp_ajax_give_hide_outdated_php_notice', 'give_hide_outdated_php_notice' );
118
119
/**
120
 * Register admin notices.
121
 *
122
 * @since 1.8.9
123
 */
124
function _give_register_admin_notices() {
125
	// Bailout.
126
	if ( ! is_admin() ) {
127
		return;
128
	}
129
130
	// Bulk action notices.
131
	if (
132
		isset( $_GET['action'] ) &&
133
		! empty( $_GET['action'] )
134
	) {
135
136
		// Add payment bulk notice.
137
		if (
138
			current_user_can( 'edit_give_payments' ) &&
139
			isset( $_GET['payment'] ) &&
140
			! empty( $_GET['payment'] )
141
		) {
142
			$payment_count = isset( $_GET['payment'] ) ? count( $_GET['payment'] ) : 0;
0 ignored issues
show
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_GET
Loading history...
143
144
			switch ( $_GET['action'] ) {
0 ignored issues
show
Detected access of super global var $_GET, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_GET
Loading history...
145 View Code Duplication
				case 'delete':
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
146
					Give()->notices->register_notice( array(
147
						'id'          => 'bulk_action_delete',
148
						'type'        => 'updated',
149
						'description' => sprintf(
150
							_n(
151
								'Successfully deleted one donation.',
152
								'Successfully deleted %d donations.',
153
								$payment_count,
154
								'give'
155
							),
156
							$payment_count ),
0 ignored issues
show
This line of the multi-line function call does not seem to be indented correctly. Expected 24 spaces, but found 28.
Loading history...
157
						'show'        => true,
158
					) );
159
160
					break;
161
162 View Code Duplication
				case 'resend-receipt':
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
163
					Give()->notices->register_notice( array(
164
						'id'          => 'bulk_action_resend_receipt',
165
						'type'        => 'updated',
166
						'description' => sprintf(
167
							_n(
168
								'Successfully sent email receipt to one recipient.',
169
								'Successfully sent email receipts to %d recipients.',
170
								$payment_count,
171
								'give'
172
							),
173
							$payment_count
174
						),
175
						'show'        => true,
176
					) );
177
					break;
178
179
				case 'set-status-publish' :
180
				case 'set-status-pending' :
181
				case 'set-status-processing' :
182
				case 'set-status-refunded' :
183
				case 'set-status-revoked' :
184
				case 'set-status-failed' :
185
				case 'set-status-cancelled' :
186
				case 'set-status-abandoned' :
187 View Code Duplication
				case 'set-status-preapproval' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
188
					Give()->notices->register_notice( array(
189
						'id'          => 'bulk_action_status_change',
190
						'type'        => 'updated',
191
						'description' => _n(
192
							'Donation status updated successfully.',
193
							'Donation statuses updated successfully.',
194
							$payment_count,
195
							'give'
196
						),
197
						'show'        => true,
198
					) );
199
					break;
200
			}// End switch().
201
		}// End if().
202
	}// End if().
203
204
	// Add give message notices.
205
	$message_notices = give_get_admin_messages_key();
206
	if ( ! empty( $message_notices ) ) {
207
		foreach ( $message_notices as $message_notice ) {
208
			// Donation reports errors.
209
			if ( current_user_can( 'view_give_reports' ) ) {
210
				switch ( $message_notice ) {
211 View Code Duplication
					case 'donation-deleted' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
212
						Give()->notices->register_notice( array(
213
							'id'          => 'give-donation-deleted',
214
							'type'        => 'updated',
215
							'description' => __( 'The donation has been deleted.', 'give' ),
216
							'show'        => true,
217
						) );
218
						break;
219 View Code Duplication
					case 'email-sent' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
220
						Give()->notices->register_notice( array(
221
							'id'          => 'give-email-sent',
222
							'type'        => 'updated',
223
							'description' => __( 'The donation receipt has been resent.', 'give' ),
224
							'show'        => true,
225
						) );
226
						break;
227 View Code Duplication
					case 'refreshed-reports' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
228
						Give()->notices->register_notice( array(
229
							'id'          => 'give-refreshed-reports',
230
							'type'        => 'updated',
231
							'description' => __( 'The reports cache has been cleared.', 'give' ),
232
							'show'        => true,
233
						) );
234
						break;
235 View Code Duplication
					case 'donation-note-deleted' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
236
						Give()->notices->register_notice( array(
237
							'id'          => 'give-donation-note-deleted',
238
							'type'        => 'updated',
239
							'description' => __( 'The donation note has been deleted.', 'give' ),
240
							'show'        => true,
241
						) );
242
						break;
243
				}// End switch().
244
			}// End if().
245
246
			// Give settings notices and errors.
247
			if ( current_user_can( 'manage_give_settings' ) ) {
248
				switch ( $message_notice ) {
249 View Code Duplication
					case 'settings-imported' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
250
						Give()->notices->register_notice( array(
251
							'id'          => 'give-settings-imported',
252
							'type'        => 'updated',
253
							'description' => __( 'The settings have been imported.', 'give' ),
254
							'show'        => true,
255
						) );
256
						break;
257 View Code Duplication
					case 'api-key-generated' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
258
						Give()->notices->register_notice( array(
259
							'id'          => 'give-api-key-generated',
260
							'type'        => 'updated',
261
							'description' => __( 'API keys have been generated.', 'give' ),
262
							'show'        => true,
263
						) );
264
						break;
265 View Code Duplication
					case 'api-key-exists' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
266
						Give()->notices->register_notice( array(
267
							'id'          => 'give-api-key-exists',
268
							'type'        => 'updated',
269
							'description' => __( 'The specified user already has API keys.', 'give' ),
270
							'show'        => true,
271
						) );
272
						break;
273 View Code Duplication
					case 'api-key-regenerated' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
274
						Give()->notices->register_notice( array(
275
							'id'          => 'give-api-key-regenerated',
276
							'type'        => 'updated',
277
							'description' => __( 'API keys have been regenerated.', 'give' ),
278
							'show'        => true,
279
						) );
280
						break;
281 View Code Duplication
					case 'api-key-revoked' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
282
						Give()->notices->register_notice( array(
283
							'id'          => 'give-api-key-revoked',
284
							'type'        => 'updated',
285
							'description' => __( 'API keys have been revoked.', 'give' ),
286
							'show'        => true,
287
						) );
288
						break;
289 View Code Duplication
					case 'sent-test-email' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
290
						Give()->notices->register_notice( array(
291
							'id'          => 'give-sent-test-email',
292
							'type'        => 'updated',
293
							'description' => __( 'The test email has been sent.', 'give' ),
294
							'show'        => true,
295
						) );
296
						break;
297 View Code Duplication
					case 'matched-success-failure-page':
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
298
						Give()->notices->register_notice( array(
299
							'id'          => 'give-matched-success-failure-page',
300
							'type'        => 'updated',
301
							'description' => __( 'You cannot set the success and failed pages to the same page', 'give' ),
302
							'show'        => true,
303
						) );
304
						break;
305
				}// End switch().
306
			}// End if().
307
308
			// Payments errors.
309
			if ( current_user_can( 'edit_give_payments' ) ) {
310
				switch ( $message_notice ) {
311 View Code Duplication
					case 'note-added' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
312
						Give()->notices->register_notice( array(
313
							'id'          => 'give-note-added',
314
							'type'        => 'updated',
315
							'description' => __( 'The donation note has been added.', 'give' ),
316
							'show'        => true,
317
						) );
318
						break;
319 View Code Duplication
					case 'payment-updated' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
320
						Give()->notices->register_notice( array(
321
							'id'          => 'give-payment-updated',
322
							'type'        => 'updated',
323
							'description' => __( 'The donation has been updated.', 'give' ),
324
							'show'        => true,
325
						) );
326
						break;
327
				}// End switch().
328
			}// End if().
329
330
			// Donor Notices.
331
			if ( current_user_can( 'edit_give_payments' ) ) {
332
				switch ( $message_notice ) {
333 View Code Duplication
					case 'donor-deleted' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
334
						Give()->notices->register_notice( array(
335
							'id'          => 'give-donor-deleted',
336
							'type'        => 'updated',
337
							'description' => __( 'The selected donor(s) has been deleted.', 'give' ),
338
							'show'        => true,
339
						) );
340
						break;
341
342 View Code Duplication
					case 'donor-donations-deleted' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
343
						Give()->notices->register_notice( array(
344
							'id'          => 'give-donor-donations-deleted',
345
							'type'        => 'updated',
346
							'description' => __( 'The selected donor(s) and the associated donation(s) has been deleted.', 'give' ),
347
							'show'        => true,
348
						) );
349
						break;
350
351 View Code Duplication
					case 'confirm-delete-donor' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
352
						Give()->notices->register_notice( array(
353
							'id'          => 'give-confirm-delete-donor',
354
							'type'        => 'updated',
355
							'description' => __( 'You must confirm to delete the selected donor(s).', 'give' ),
356
							'show'        => true,
357
						) );
358
						break;
359
360 View Code Duplication
					case 'invalid-donor-id' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
361
						Give()->notices->register_notice( array(
362
							'id'          => 'give-invalid-donor-id',
363
							'type'        => 'updated',
364
							'description' => __( 'Invalid Donor ID.', 'give' ),
365
							'show'        => true,
366
						) );
367
						break;
368
369
					case 'donor-delete-failed' :
370
						Give()->notices->register_notice( array(
371
							'id'          => 'give-donor-delete-failed',
372
							'type'        => 'error',
373
							'description' => __( 'Unable to delete selected donor(s).', 'give' ),
374
							'show'        => true,
375
						) );
376
						break;
377
378 View Code Duplication
					case 'email-added' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
379
						Give()->notices->register_notice( array(
380
							'id'          => 'give-email-added',
381
							'type'        => 'updated',
382
							'description' => __( 'Donor email added.', 'give' ),
383
							'show'        => true,
384
						) );
385
						break;
386
387 View Code Duplication
					case 'email-removed' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
388
						Give()->notices->register_notice( array(
389
							'id'          => 'give-email-removed',
390
							'type'        => 'updated',
391
							'description' => __( 'Donor email removed.', 'give' ),
392
							'show'        => true,
393
						) );
394
						break;
395
396 View Code Duplication
					case 'email-remove-failed' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
397
						Give()->notices->register_notice( array(
398
							'id'          => 'give-email-remove-failed',
399
							'type'        => 'updated',
400
							'description' => __( 'Failed to remove donor email.', 'give' ),
401
							'show'        => true,
402
						) );
403
						break;
404
405 View Code Duplication
					case 'primary-email-updated' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
406
						Give()->notices->register_notice( array(
407
							'id'          => 'give-primary-email-updated',
408
							'type'        => 'updated',
409
							'description' => __( 'Primary email updated for donor.', 'give' ),
410
							'show'        => true,
411
						) );
412
						break;
413
414 View Code Duplication
					case 'primary-email-failed' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
415
						Give()->notices->register_notice( array(
416
							'id'          => 'give-primary-email-failed',
417
							'type'        => 'updated',
418
							'description' => __( 'Failed to set primary email.', 'give' ),
419
							'show'        => true,
420
						) );
421
						break;
422
423 View Code Duplication
					case 'reconnect-user' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
424
						Give()->notices->register_notice( array(
425
							'id'          => 'give-reconnect-user',
426
							'type'        => 'updated',
427
							'description' => __( 'User has been successfully connected with Donor.', 'give' ),
428
							'show'        => true,
429
						) );
430
						break;
431
432 View Code Duplication
					case 'profile-updated' :
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
433
						Give()->notices->register_notice( array(
434
							'id'          => 'give-profile-updated',
435
							'type'        => 'updated',
436
							'description' => __( 'Donor information updated successfully.', 'give' ),
437
							'show'        => true,
438
						) );
439
						break;
440
				}// End switch().
441
			}// End if().
442
		}
443
	}
444
}
445
446
add_action( 'admin_notices', '_give_register_admin_notices', - 1 );
447
448
449
/**
450
 * Display admin bar when active.
451
 *
452
 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
453
 *
454
 * @return bool
455
 */
456
function _give_show_test_mode_notice_in_admin_bar( $wp_admin_bar ) {
457
	$is_test_mode = ! empty( $_POST['test_mode'] ) ?
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
458
		give_is_setting_enabled( $_POST['test_mode'] ) :
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
459
		give_is_test_mode();
460
461
	if (
462
		! current_user_can( 'view_give_reports' ) ||
463
		! $is_test_mode
464
	) {
465
		return false;
466
	}
467
468
	// Add the main site admin menu item.
469
	$wp_admin_bar->add_menu( array(
470
		'id'     => 'give-test-notice',
471
		'href'   => admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=gateways' ),
472
		'parent' => 'top-secondary',
473
		'title'  => __( 'Give Test Mode Active', 'give' ),
474
		'meta'   => array(
475
			'class' => 'give-test-mode-active',
476
		),
477
	) );
478
479
	return true;
480
}
481
482
add_action( 'admin_bar_menu', '_give_show_test_mode_notice_in_admin_bar', 1000, 1 );
483
484
/**
485
 * Outputs the Give admin bar CSS.
486
 */
487
function _give_test_mode_notice_admin_bar_css() {
488
	if ( ! give_is_test_mode() ) {
489
		return;
490
	}
491
	?>
492
	<style>
493
		#wpadminbar .give-test-mode-active > .ab-item {
494
			color: #fff;
495
			background-color: #ffba00;
496
		}
497
498
		#wpadminbar .give-test-mode-active:hover > .ab-item, #wpadminbar .give-test-mode-active:hover > .ab-item {
499
			background-color: rgba(203, 144, 0, 1) !important;
500
			color: #fff !important;
501
		}
502
	</style>
503
	<?php
504
}
505
506
add_action( 'admin_head', '_give_test_mode_notice_admin_bar_css' );
507
508
509
/**
510
 * Add Link to Import page in from donation archive and donation single page
511
 *
512
 * @since 1.8.13
513
 */
514
function give_import_page_link_callback() {
515
	?>
516
	<a href="<?php echo esc_url( give_import_page_url() ); ?>"
517
	   class="page-import-action page-title-action"><?php _e( 'Import Donations', 'give' ); ?></a>
518
519
	<?php
520
	// Check if view donation single page only.
521
	if ( ! empty( $_REQUEST['view'] ) && 'view-payment-details' === (string) give_clean( $_REQUEST['view'] ) && 'give-payment-history' === give_clean( $_REQUEST['page'] ) ) {
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_REQUEST
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
522
		?>
523
		<style type="text/css">
524
			.wrap #transaction-details-heading {
525
				display: inline-block;
526
			}
527
		</style>
528
		<?php
529
	}
530
}
531
532
add_action( 'give_payments_page_top', 'give_import_page_link_callback', 11 );
533
534
/**
535
 * Load donation import ajax callback
536
 * Fire when importing from CSV start
537
 *
538
 * @since  1.8.13
539
 *
540
 * @return json $json_data
541
 */
542
function give_donation_import_callback() {
543
544
	// Disable Give cache
545
	Give_Cache::get_instance()->disable();
546
547
	$import_setting = array();
548
	$fields         = isset( $_POST['fields'] ) ? $_POST['fields'] : null;
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
549
550
	parse_str( $fields, $output );
551
552
	$import_setting['create_user'] = $output['create_user'];
553
	$import_setting['mode']        = $output['mode'];
554
	$import_setting['delimiter']   = $output['delimiter'];
555
	$import_setting['csv']         = $output['csv'];
556
	$import_setting['delete_csv']  = $output['delete_csv'];
557
	$import_setting['dry_run']     = $output['dry_run'];
558
559
	// Parent key id.
560
	$main_key = maybe_unserialize( $output['main_key'] );
561
562
	$current    = absint( $_REQUEST['current'] );
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
563
	$total_ajax = absint( $_REQUEST['total_ajax'] );
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
564
	$start      = absint( $_REQUEST['start'] );
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
565
	$end        = absint( $_REQUEST['end'] );
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
566
	$next       = absint( $_REQUEST['next'] );
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
567
	$total      = absint( $_REQUEST['total'] );
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
568
	$per_page   = absint( $_REQUEST['per_page'] );
0 ignored issues
show
Detected access of super global var $_REQUEST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_REQUEST
Loading history...
569
	if ( empty( $output['delimiter'] ) ) {
570
		$delimiter = ',';
571
	} else {
572
		$delimiter = $output['delimiter'];
573
	}
574
575
	// Processing done here.
576
	$raw_data                  = give_get_donation_data_from_csv( $output['csv'], $start, $end, $delimiter );
577
	$raw_key                   = maybe_unserialize( $output['mapto'] );
578
	$import_setting['raw_key'] = $raw_key;
579
580
	if ( ! empty( $output['dry_run'] ) ) {
581
		$import_setting['csv_raw_data'] = give_get_donation_data_from_csv( $output['csv'], 1, $end, $delimiter );
582
583
		$import_setting['donors_list'] = Give()->donors->get_donors( array(
584
			'number' => - 1,
585
			'fields' => array( 'id', 'user_id', 'email' ),
586
		) );
587
	}
588
589
	// Prevent normal emails.
590
	remove_action( 'give_complete_donation', 'give_trigger_donation_receipt', 999 );
591
	remove_action( 'give_insert_user', 'give_new_user_notification', 10 );
592
	remove_action( 'give_insert_payment', 'give_payment_save_page_data' );
593
594
	$current_key = $start;
595
	foreach ( $raw_data as $row_data ) {
596
		$import_setting['donation_key'] = $current_key;
597
		give_save_import_donation_to_db( $raw_key, $row_data, $main_key, $import_setting );
598
		$current_key ++;
599
	}
600
601
	// Check if function exists or not.
602
	if ( function_exists( 'give_payment_save_page_data' ) ) {
603
		add_action( 'give_insert_payment', 'give_payment_save_page_data' );
604
	}
605
	add_action( 'give_insert_user', 'give_new_user_notification', 10, 2 );
606
	add_action( 'give_complete_donation', 'give_trigger_donation_receipt', 999 );
607
608
	if ( $next == false ) {
0 ignored issues
show
Found "== false". Use Yoda Condition checks, you must
Loading history...
609
		$json_data = array(
610
			'success' => true,
611
			'message' => __( 'All donation uploaded successfully!', 'give' ),
612
		);
613
	} else {
614
		$index_start = $start;
615
		$index_end   = $end;
616
		$last        = false;
617
		$next        = true;
618
		if ( $next ) {
619
			$index_start = $index_start + $per_page;
620
			$index_end   = $per_page + ( $index_start - 1 );
621
		}
622
		if ( $index_end >= $total ) {
623
			$index_end = $total;
624
			$last      = true;
625
		}
626
		$json_data = array(
627
			'raw_data' => $raw_data,
628
			'raw_key'  => $raw_key,
629
			'next'     => $next,
630
			'start'    => $index_start,
631
			'end'      => $index_end,
632
			'last'     => $last,
633
		);
634
	}
635
636
	$url              = give_import_page_url( array(
637
		'step'          => '4',
638
		'importer-type' => 'import_donations',
639
		'csv'           => $output['csv'],
640
		'total'         => $total,
641
		'delete_csv'    => $import_setting['delete_csv'],
642
		'success'       => ( isset( $json_data['success'] ) ? $json_data['success'] : '' ),
643
		'dry_run'       => $output['dry_run'],
644
	) );
645
	$json_data['url'] = $url;
646
647
	$current ++;
648
	$json_data['current'] = $current;
649
650
	$percentage              = ( 100 / ( $total_ajax + 1 ) ) * $current;
651
	$json_data['percentage'] = $percentage;
652
653
	// Enable Give cache
654
	Give_Cache::get_instance()->enable();
655
656
	$json_data = apply_filters( 'give_import_ajax_responces', $json_data, $fields );
657
	wp_die( json_encode( $json_data ) );
658
}
659
660
add_action( 'wp_ajax_give_donation_import', 'give_donation_import_callback' );
661
662
/**
663
 * Load core settings import ajax callback
664
 * Fire when importing from JSON start
665
 *
666
 * @since  1.8.17
667
 *
668
 * @return json $json_data
669
 */
670
671
function give_core_settings_import_callback() {
672
	$fields = isset( $_POST['fields'] ) ? $_POST['fields'] : null;
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
673
	parse_str( $fields, $fields );
674
675
	$json_data['success'] = false;
676
677
	/**
678
	 * Filter to Modify fields that are being pass by the ajax before importing of the core setting start.
679
	 *
680
	 * @access public
681
	 *
682
	 * @since  1.8.17
683
	 *
684
	 * @param array $fields
685
	 *
686
	 * @return array $fields
687
	 */
688
	$fields = (array) apply_filters( 'give_import_core_settings_fields', $fields );
689
690
	$file_name = ( ! empty( $fields['file_name'] ) ? give_clean( $fields['file_name'] ) : false );
691
692
	if ( ! empty( $file_name ) ) {
693
		$type = ( ! empty( $fields['type'] ) ? give_clean( $fields['type'] ) : 'merge' );
694
695
		// Get the json data from the file and then alter it in array format
696
		$json_string   = give_get_core_settings_json( $file_name );
0 ignored issues
show
It seems like $file_name defined by !empty($fields['file_nam...s['file_name']) : false on line 690 can also be of type array; however, give_get_core_settings_json() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
697
		$json_to_array = json_decode( $json_string, true );
698
699
		// get the current settign from the options table.
700
		$host_give_options = get_option( 'give_settings', array() );
701
702
		// Save old settins for backup.
703
		update_option( 'give_settings_old', $host_give_options, false );
704
705
		/**
706
		 * Filter to Modify Core Settings that are being going to get import in options table as give settings.
707
		 *
708
		 * @access public
709
		 *
710
		 * @since  1.8.17
711
		 *
712
		 * @param array $json_to_array     Setting that are being going to get imported
713
		 * @param array $type              Type of Import
714
		 * @param array $host_give_options Setting old setting that used to be in the options table.
715
		 * @param array $fields            Data that is being send from the ajax
716
		 *
717
		 * @return array $json_to_array Setting that are being going to get imported
718
		 */
719
		$json_to_array = (array) apply_filters( 'give_import_core_settings_data', $json_to_array, $type, $host_give_options, $fields );
720
721
		update_option( 'give_settings', $json_to_array, false );
722
723
		$json_data['success'] = true;
724
	}
725
726
	$json_data['percentage'] = 100;
727
728
	/**
729
	 * Filter to Modify core import setting page url
730
	 *
731
	 * @access public
732
	 *
733
	 * @since  1.8.17
734
	 *
735
	 * @return array $url
736
	 */
737
	$json_data['url'] = give_import_page_url( (array) apply_filters( 'give_import_core_settings_success_url', array(
738
		'step'          => ( empty( $json_data['success'] ) ? '1' : '3' ),
739
		'importer-type' => 'import_core_setting',
740
		'success'       => ( empty( $json_data['success'] ) ? '0' : '1' ),
741
	) ) );
742
743
	wp_send_json( $json_data );
744
}
745
746
add_action( 'wp_ajax_give_core_settings_import', 'give_core_settings_import_callback' );
747
748
/**
749
 * Initializes blank slate content if a list table is empty.
750
 *
751
 * @since 1.8.13
752
 */
753
function give_blank_slate() {
754
	$blank_slate = new Give_Blank_Slate();
755
	$blank_slate->init();
756
}
757
758
add_action( 'current_screen', 'give_blank_slate' );
759
760
/**
761
 * Validate Fields of User Profile
762
 *
763
 * @param object   $errors Object of WP Errors.
764
 * @param int|bool $update True or False.
765
 * @param object   $user   WP User Data.
766
 *
767
 * @since 2.0
768
 *
769
 * @return mixed
770
 */
771
function give_validate_user_profile( $errors, $update, $user ) {
0 ignored issues
show
The parameter $update is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
772
773
	if ( ! empty( $_POST['action'] ) && ( 'adduser' === $_POST['action'] || 'createuser' === $_POST['action'] ) ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
774
		return;
775
	}
776
777
	if ( ! empty( $user->ID ) ) {
778
		$donor = Give()->donors->get_donor_by( 'user_id', $user->ID );
779
780
		if ( $donor ) {
781
			// If Donor is attached with User, then validate first name.
782
			if ( empty( $_POST['first_name'] ) ) {
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
783
				$errors->add(
784
					'empty_first_name',
785
					sprintf(
786
						'<strong>%1$s:</strong> %2$s',
787
						__( 'ERROR', 'give' ),
788
						__( 'Please enter your first name.', 'give' )
789
					)
790
				);
791
			}
792
		}
793
	}
794
795
}
796
797
add_action( 'user_profile_update_errors', 'give_validate_user_profile', 10, 3 );
798
799
/**
800
 * Show Donor Information on User Profile Page.
801
 *
802
 * @param object $user User Object.
803
 *
804
 * @since 2.0
805
 */
806
function give_donor_information_profile_fields( $user ) {
807
	$donor = Give()->donors->get_donor_by( 'user_id', $user->ID );
808
809
	// Display Donor Information, only if donor is attached with User.
810
	if ( ! empty( $donor->user_id ) ) {
811
		?>
812
		<table class="form-table">
813
			<tbody>
814
			<tr>
815
				<th scope="row"><?php _e( 'Donor', 'give' ); ?></th>
816
				<td>
817
					<a href="<?php echo admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ); ?>">
0 ignored issues
show
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'admin_url'
Loading history...
818
						<?php _e( 'View Donor Information', 'give' ); ?>
819
					</a>
820
				</td>
821
			</tr>
822
			</tbody>
823
		</table>
824
		<?php
825
	}
826
}
827
828
add_action( 'personal_options', 'give_donor_information_profile_fields' );
829
/**
830
 * Get Array of WP User Roles.
831
 *
832
 * @since 1.8.13
833
 *
834
 * @return array
835
 */
836
function give_get_user_roles() {
837
	$user_roles = array();
838
839
	// Loop through User Roles.
840
	foreach ( get_editable_roles() as $role_name => $role_info ) :
841
		$user_roles[ $role_name ] = $role_info['name'];
842
	endforeach;
843
844
	return $user_roles;
845
}
846
847
848
/**
849
 * Ajax handle for donor address.
850
 *
851
 * @since 2.0
852
 *
853
 * @return string
854
 */
855
function __give_ajax_donor_manage_addresses() {
856
	// Bailout.
857
	if (
858
		empty( $_POST['form'] ) ||
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
859
		empty( $_POST['donorID'] )
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
860
	) {
861
		wp_send_json_error( array(
862
			'error' => 1,
863
		) );
864
	}
865
866
	$post                  = give_clean( wp_parse_args( $_POST ) );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
867
	$donorID               = absint( $post['donorID'] );
868
	$form_data             = give_clean( wp_parse_args( $post['form'] ) );
869
	$is_multi_address_type = ( 'billing' === $form_data['address-id'] || false !== strpos( $form_data['address-id'], '_' ) );
870
	$address_type          = false !== strpos( $form_data['address-id'], '_' ) ?
871
		array_shift( explode( '_', $form_data['address-id'] ) ) :
872
		$form_data['address-id'];
873
	$address_id            = false !== strpos( $form_data['address-id'], '_' ) ?
874
		array_pop( explode( '_', $form_data['address-id'] ) ) :
875
		null;
876
	$response_data         = array(
877
		'action' => $form_data['address-action'],
878
		'id'     => $form_data['address-id'],
879
	);
880
881
	// Security check.
882 View Code Duplication
	if ( ! wp_verify_nonce( $form_data['_wpnonce'], 'give-manage-donor-addresses' ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
883
		wp_send_json_error( array(
884
				'error'     => 1,
885
				'error_msg' => wp_sprintf(
886
					'<div class="notice notice-error"><p>%s</p></div>',
887
					__( 'Error: Security issue.', 'give' )
888
				),
889
			)
890
		);
891
	}
892
893
	$donor = new Give_Donor( $donorID );
894
895
	// Verify donor.
896
	if ( ! $donor->id ) {
897
		wp_send_json_error( array(
898
			'error' => 3,
899
		) );
900
	}
901
902
	// Unset all data except address.
903
	unset(
904
		$form_data['_wpnonce'],
905
		$form_data['address-action'],
906
		$form_data['address-id']
907
	);
908
909
	// Process action.
910
	switch ( $response_data['action'] ) {
911
912
		case 'add':
913 View Code Duplication
			if ( ! $donor->add_address( "{$address_type}[]", $form_data ) ) {
0 ignored issues
show
It seems like $form_data defined by give_clean(wp_parse_args($post['form'])) on line 868 can also be of type string; however, Give_Donor::add_address() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
This code seems to be duplicated across your project.

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

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

Loading history...
914
				wp_send_json_error( array(
915
						'error'     => 1,
916
						'error_msg' => wp_sprintf(
917
							'<div class="notice notice-error"><p>%s</p></div>',
918
							__( 'Error: Unable to save the address. Please check if address already exist.', 'give' )
919
						),
920
					)
921
				);
922
			}
923
924
			$total_addresses = count( $donor->address[ $address_type ] );
925
926
			$address_index = $is_multi_address_type ?
927
				$total_addresses - 1 :
928
				$address_type;
929
930
			$array_keys = array_keys( $donor->address[ $address_type ] );
931
932
			$address_id = $is_multi_address_type ?
933
				end( $array_keys ) :
934
				$address_type;
935
936
			$response_data['address_html'] = __give_get_format_address(
937
				end( $donor->address['billing'] ),
938
				array(
939
					// We can add only billing address from donor screen.
940
					'type'  => 'billing',
941
					'id'    => $address_id,
942
					'index' => ++ $address_index,
943
				)
944
			);
945
			$response_data['success_msg']  = wp_sprintf(
946
				'<div class="notice updated"><p>%s</p></div>',
947
				__( 'Successfully added a new address to the donor.', 'give' )
948
			);
949
950
			if ( $is_multi_address_type ) {
951
				$response_data['id'] = "{$response_data['id']}_{$address_index}";
952
			}
953
954
			break;
955
956
		case 'remove':
957 View Code Duplication
			if ( ! $donor->remove_address( $response_data['id'] ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

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

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

Loading history...
958
				wp_send_json_error( array(
959
						'error'     => 2,
960
						'error_msg' => wp_sprintf(
961
							'<div class="notice notice-error"><p>%s</p></div>',
962
							__( 'Error: Unable to delete address.', 'give' )
963
						),
964
					)
965
				);
966
			}
967
968
			$response_data['success_msg'] = wp_sprintf(
969
				'<div class="notice updated"><p>%s</p></div>',
970
				__( 'Successfully removed a address of donor.', 'give' )
971
			);
972
973
			break;
974
975
		case 'update':
976 View Code Duplication
			if ( ! $donor->update_address( $response_data['id'], $form_data ) ) {
0 ignored issues
show
It seems like $form_data defined by give_clean(wp_parse_args($post['form'])) on line 868 can also be of type string; however, Give_Donor::update_address() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
This code seems to be duplicated across your project.

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

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

Loading history...
977
				wp_send_json_error( array(
978
						'error'     => 3,
979
						'error_msg' => wp_sprintf(
980
							'<div class="notice notice-error"><p>%s</p></div>',
981
							__( 'Error: Unable to update address. Please check if address already exist.', 'give' )
982
						),
983
					)
984
				);
985
			}
986
987
			$response_data['address_html'] = __give_get_format_address(
988
				$is_multi_address_type ?
989
					$donor->address[ $address_type ][ $address_id ] :
990
					$donor->address[ $address_type ],
991
				array(
992
					'type'  => $address_type,
993
					'id'    => $address_id,
994
					'index' => $address_id,
995
				)
996
			);
997
			$response_data['success_msg']  = wp_sprintf(
998
				'<div class="notice updated"><p>%s</p></div>',
999
				__( 'Successfully updated a address of donor', 'give' )
1000
			);
1001
1002
			break;
1003
	}// End switch().
1004
1005
	wp_send_json_success( $response_data );
1006
}
1007
1008
add_action( 'wp_ajax_donor_manage_addresses', '__give_ajax_donor_manage_addresses' );
1009
1010
/**
1011
 * Admin donor billing address label
1012
 *
1013
 * @since 2.0
1014
 *
1015
 * @param string $address_label
1016
 *
1017
 * @return string
1018
 */
1019
function __give_donor_billing_address_label( $address_label ) {
0 ignored issues
show
The parameter $address_label is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1020
	$address_label = __( 'Billing Address', 'give' );
1021
1022
	return $address_label;
1023
}
1024
1025
add_action( 'give_donor_billing_address_label', '__give_donor_billing_address_label' );
1026
1027
/**
1028
 * Admin donor personal address label
1029
 *
1030
 * @since 2.0
1031
 *
1032
 * @param string $address_label
1033
 *
1034
 * @return string
1035
 */
1036
function __give_donor_personal_address_label( $address_label ) {
0 ignored issues
show
The parameter $address_label is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1037
	$address_label = __( 'Personal Address', 'give' );
1038
1039
	return $address_label;
1040
}
1041
1042
add_action( 'give_donor_personal_address_label', '__give_donor_personal_address_label' );
1043
1044
/**
1045
 * Update Donor Information when User Profile is updated from admin.
1046
 * Note: for internal use only.
1047
 *
1048
 * @param int $user_id
1049
 *
1050
 * @access public
1051
 * @since  2.0
1052
 *
1053
 * @return bool
1054
 */
1055
function give_update_donor_name_on_user_update( $user_id = 0 ) {
1056
1057
	if ( current_user_can( 'edit_user', $user_id ) ) {
1058
1059
		$donor = new Give_Donor( $user_id, true );
1060
1061
		// Bailout, if donor doesn't exists.
1062
		if ( ! $donor ) {
1063
			return false;
1064
		}
1065
1066
		// Get User First name and Last name.
1067
		$first_name = ( $_POST['first_name'] ) ? give_clean( $_POST['first_name'] ) : get_user_meta( $user_id, 'first_name', true );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1068
		$last_name  = ( $_POST['last_name'] ) ? give_clean( $_POST['last_name'] ) : get_user_meta( $user_id, 'last_name', true );
0 ignored issues
show
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
Detected usage of a non-validated input variable: $_POST
Loading history...
Detected usage of a non-sanitized input variable: $_POST
Loading history...
get_user_meta() usage is highly discouraged, check VIP documentation on "Working with wp_users"
Loading history...
1069
		$full_name  = strip_tags( wp_unslash( trim( "{$first_name} {$last_name}" ) ) );
1070
1071
		// Assign User First name and Last name to Donor.
1072
		Give()->donors->update( $donor->id, array(
1073
			'name' => $full_name,
1074
		) );
1075
		Give()->donor_meta->update_meta( $donor->id, '_give_donor_first_name', $first_name );
1076
		Give()->donor_meta->update_meta( $donor->id, '_give_donor_last_name', $last_name );
1077
1078
	}
1079
}
1080
1081
add_action( 'edit_user_profile_update', 'give_update_donor_name_on_user_update', 10 );
1082
add_action( 'personal_options_update', 'give_update_donor_name_on_user_update', 10 );
1083
1084
1085
/**
1086
 * Updates the email address of a donor record when the email on a user is updated
1087
 * Note: for internal use only.
1088
 *
1089
 * @since  1.4.3
1090
 * @access public
1091
 *
1092
 * @param  int          $user_id       User ID.
1093
 * @param  WP_User|bool $old_user_data User data.
1094
 *
1095
 * @return bool
1096
 */
1097
function give_update_donor_email_on_user_update( $user_id = 0, $old_user_data = false ) {
0 ignored issues
show
The parameter $old_user_data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1098
1099
	$donor = new Give_Donor( $user_id, true );
1100
1101
	if ( ! $donor ) {
1102
		return false;
1103
	}
1104
1105
	$user = get_userdata( $user_id );
1106
1107
	if ( ! empty( $user ) && $user->user_email !== $donor->email ) {
1108
1109
		$success = Give()->donors->update( $donor->id, array(
1110
			'email' => $user->user_email,
1111
		) );
1112
1113
		if ( $success ) {
1114
			// Update some payment meta if we need to
1115
			$payments_array = explode( ',', $donor->payment_ids );
1116
1117
			if ( ! empty( $payments_array ) ) {
1118
1119
				foreach ( $payments_array as $payment_id ) {
1120
1121
					give_update_payment_meta( $payment_id, 'email', $user->user_email );
1122
1123
				}
1124
			}
1125
1126
			/**
1127
			 * Fires after updating donor email on user update.
1128
			 *
1129
			 * @since 1.4.3
1130
			 *
1131
			 * @param  WP_User    $user  WordPress User object.
1132
			 * @param  Give_Donor $donor Give donor object.
1133
			 */
1134
			do_action( 'give_update_donor_email_on_user_update', $user, $donor );
1135
1136
		}
1137
	}
1138
1139
}
1140
1141
add_action( 'profile_update', 'give_update_donor_email_on_user_update', 10, 2 );
1142
1143
1144
/**
1145
 * Flushes Give's cache.
1146
 */
1147
function give_cache_flush() {
1148
	$result = Give_Cache::flush_cache();
1149
1150
	if ( $result ) {
1151
		wp_send_json_success( array(
1152
			'message' => __( 'Cache flushed successfully.', 'give' ),
1153
		));
1154
	} else {
1155
		wp_send_json_error( array(
1156
			'message' => __( 'An error occured while flushing the cache.', 'give' ),
1157
		));
1158
	}
1159
}
1160
1161
add_action( 'wp_ajax_give_cache_flush', 'give_cache_flush', 10, 0 );
1162