Issues (1282)

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 (39 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, GiveWP
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'] ) || ! current_user_can( 'edit_give_forms' ) ) {
24
		die();
25
	}
26
27
	$wp_editor                     = json_decode( base64_decode( $_POST['wp_editor'] ), true );
28
	$wp_editor[2]['textarea_name'] = $_POST['textarea_name'];
29
30
	wp_editor( $wp_editor[0], $_POST['wp_editor_id'], $wp_editor[2] );
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
 * @return bool
42
 * @since 1.8
43
 *
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'] ) : '';
56
57
	// Bailout.
58
	if (
59
		empty( $current_page )
60
		|| empty( $_GET['_wp_http_referer'] )
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'] )
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
 * @return void
94
 * @since 1.8.9
95
 *
96
 */
97
function give_hide_outdated_php_notice() {
98
99
	if ( ! isset( $_POST['_give_hide_outdated_php_notices_shortly'] ) || ! current_user_can( 'manage_give_settings' ) ) {
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;
143
144
			switch ( $_GET['action'] ) {
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(
147
						array(
148
							'id'          => 'bulk_action_delete',
149
							'type'        => 'updated',
150
							'description' => sprintf(
151
								_n(
152
									'Successfully deleted one donation.',
153
									'Successfully deleted %d donations.',
154
									$payment_count,
155
									'give'
156
								),
157
								$payment_count
158
							),
159
							'show'        => true,
160
						)
161
					);
162
163
					break;
164
165 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...
166
					Give()->notices->register_notice(
167
						array(
168
							'id'          => 'bulk_action_resend_receipt',
169
							'type'        => 'updated',
170
							'description' => sprintf(
171
								_n(
172
									'Successfully sent email receipt to one recipient.',
173
									'Successfully sent email receipts to %d recipients.',
174
									$payment_count,
175
									'give'
176
								),
177
								$payment_count
178
							),
179
							'show'        => true,
180
						)
181
					);
182
					break;
183
184
				case 'set-status-publish':
185
				case 'set-status-pending':
186
				case 'set-status-processing':
187
				case 'set-status-refunded':
188
				case 'set-status-revoked':
189
				case 'set-status-failed':
190
				case 'set-status-cancelled':
191
				case 'set-status-abandoned':
192 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...
193
					Give()->notices->register_notice(
194
						array(
195
							'id'          => 'bulk_action_status_change',
196
							'type'        => 'updated',
197
							'description' => _n(
198
								'Donation status updated successfully.',
199
								'Donation statuses updated successfully.',
200
								$payment_count,
201
								'give'
202
							),
203
							'show'        => true,
204
						)
205
					);
206
					break;
207
			}// End switch().
208
		}// End if().
209
	}// End if().
210
211
	// Add give message notices.
212
	$message_notices = give_get_admin_messages_key();
213
	if ( ! empty( $message_notices ) ) {
214
		foreach ( $message_notices as $message_notice ) {
215
			// Donation reports errors.
216
			if ( current_user_can( 'view_give_reports' ) ) {
217
				switch ( $message_notice ) {
218 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...
219
						Give()->notices->register_notice(
220
							array(
221
								'id'          => 'give-donation-deleted',
222
								'type'        => 'updated',
223
								'description' => __( 'The donation has been deleted.', 'give' ),
224
								'show'        => true,
225
							)
226
						);
227
						break;
228 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...
229
						Give()->notices->register_notice(
230
							array(
231
								'id'          => 'give-email-sent',
232
								'type'        => 'updated',
233
								'description' => __( 'The donation receipt has been resent.', 'give' ),
234
								'show'        => true,
235
							)
236
						);
237
						break;
238 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...
239
						Give()->notices->register_notice(
240
							array(
241
								'id'          => 'give-refreshed-reports',
242
								'type'        => 'updated',
243
								'description' => __( 'The reports cache has been cleared.', 'give' ),
244
								'show'        => true,
245
							)
246
						);
247
						break;
248 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...
249
						Give()->notices->register_notice(
250
							array(
251
								'id'          => 'give-donation-note-deleted',
252
								'type'        => 'updated',
253
								'description' => __( 'The donation note has been deleted.', 'give' ),
254
								'show'        => true,
255
							)
256
						);
257
						break;
258
				}// End switch().
259
			}// End if().
260
261
			// Give settings notices and errors.
262
			if ( current_user_can( 'manage_give_settings' ) ) {
263
				switch ( $message_notice ) {
264 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...
265
						Give()->notices->register_notice(
266
							array(
267
								'id'          => 'give-settings-imported',
268
								'type'        => 'updated',
269
								'description' => __( 'The settings have been imported.', 'give' ),
270
								'show'        => true,
271
							)
272
						);
273
						break;
274 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...
275
						Give()->notices->register_notice(
276
							array(
277
								'id'          => 'give-api-key-generated',
278
								'type'        => 'updated',
279
								'description' => __( 'API keys have been generated.', 'give' ),
280
								'show'        => true,
281
							)
282
						);
283
						break;
284 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...
285
						Give()->notices->register_notice(
286
							array(
287
								'id'          => 'give-api-key-exists',
288
								'type'        => 'updated',
289
								'description' => __( 'The specified user already has API keys.', 'give' ),
290
								'show'        => true,
291
							)
292
						);
293
						break;
294 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...
295
						Give()->notices->register_notice(
296
							array(
297
								'id'          => 'give-api-key-regenerated',
298
								'type'        => 'updated',
299
								'description' => __( 'API keys have been regenerated.', 'give' ),
300
								'show'        => true,
301
							)
302
						);
303
						break;
304 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...
305
						Give()->notices->register_notice(
306
							array(
307
								'id'          => 'give-api-key-revoked',
308
								'type'        => 'updated',
309
								'description' => __( 'API keys have been revoked.', 'give' ),
310
								'show'        => true,
311
							)
312
						);
313
						break;
314 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...
315
						Give()->notices->register_notice(
316
							array(
317
								'id'          => 'give-sent-test-email',
318
								'type'        => 'updated',
319
								'description' => __( 'The test email has been sent.', 'give' ),
320
								'show'        => true,
321
							)
322
						);
323
						break;
324 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...
325
						Give()->notices->register_notice(
326
							array(
327
								'id'          => 'give-matched-success-failure-page',
328
								'type'        => 'updated',
329
								'description' => __( 'You cannot set the success and failed pages to the same page', 'give' ),
330
								'show'        => true,
331
							)
332
						);
333
						break;
334
				}// End switch().
335
			}// End if().
336
337
			// Payments errors.
338
			if ( current_user_can( 'edit_give_payments' ) ) {
339
				switch ( $message_notice ) {
340 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...
341
						Give()->notices->register_notice(
342
							array(
343
								'id'          => 'give-note-added',
344
								'type'        => 'updated',
345
								'description' => __( 'The donation note has been added.', 'give' ),
346
								'show'        => true,
347
							)
348
						);
349
						break;
350 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...
351
						Give()->notices->register_notice(
352
							array(
353
								'id'          => 'give-payment-updated',
354
								'type'        => 'updated',
355
								'description' => __( 'The donation has been updated.', 'give' ),
356
								'show'        => true,
357
							)
358
						);
359
						break;
360
				}// End switch().
361
			}// End if().
362
363
			// Donor Notices.
364
			if ( current_user_can( 'edit_give_payments' ) ) {
365
				switch ( $message_notice ) {
366 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...
367
						Give()->notices->register_notice(
368
							array(
369
								'id'          => 'give-donor-deleted',
370
								'type'        => 'updated',
371
								'description' => __( 'The selected donor(s) has been deleted.', 'give' ),
372
								'show'        => true,
373
							)
374
						);
375
						break;
376
377 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...
378
						Give()->notices->register_notice(
379
							array(
380
								'id'          => 'give-donor-donations-deleted',
381
								'type'        => 'updated',
382
								'description' => __( 'The selected donor(s) and the associated donation(s) has been deleted.', 'give' ),
383
								'show'        => true,
384
							)
385
						);
386
						break;
387
388 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...
389
						Give()->notices->register_notice(
390
							array(
391
								'id'          => 'give-confirm-delete-donor',
392
								'type'        => 'updated',
393
								'description' => __( 'You must confirm to delete the selected donor(s).', 'give' ),
394
								'show'        => true,
395
							)
396
						);
397
						break;
398
399 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...
400
						Give()->notices->register_notice(
401
							array(
402
								'id'          => 'give-invalid-donor-id',
403
								'type'        => 'updated',
404
								'description' => __( 'Invalid Donor ID.', 'give' ),
405
								'show'        => true,
406
							)
407
						);
408
						break;
409
410
					case 'donor-delete-failed':
411
						Give()->notices->register_notice(
412
							array(
413
								'id'          => 'give-donor-delete-failed',
414
								'type'        => 'error',
415
								'description' => __( 'Unable to delete selected donor(s).', 'give' ),
416
								'show'        => true,
417
							)
418
						);
419
						break;
420
421 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...
422
						Give()->notices->register_notice(
423
							array(
424
								'id'          => 'give-email-added',
425
								'type'        => 'updated',
426
								'description' => __( 'Donor email added.', 'give' ),
427
								'show'        => true,
428
							)
429
						);
430
						break;
431
432 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...
433
						Give()->notices->register_notice(
434
							array(
435
								'id'          => 'give-email-removed',
436
								'type'        => 'updated',
437
								'description' => __( 'Donor email removed.', 'give' ),
438
								'show'        => true,
439
							)
440
						);
441
						break;
442
443 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...
444
						Give()->notices->register_notice(
445
							array(
446
								'id'          => 'give-email-remove-failed',
447
								'type'        => 'updated',
448
								'description' => __( 'Failed to remove donor email.', 'give' ),
449
								'show'        => true,
450
							)
451
						);
452
						break;
453
454 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...
455
						Give()->notices->register_notice(
456
							array(
457
								'id'          => 'give-primary-email-updated',
458
								'type'        => 'updated',
459
								'description' => __( 'Primary email updated for donor.', 'give' ),
460
								'show'        => true,
461
							)
462
						);
463
						break;
464
465 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...
466
						Give()->notices->register_notice(
467
							array(
468
								'id'          => 'give-primary-email-failed',
469
								'type'        => 'updated',
470
								'description' => __( 'Failed to set primary email.', 'give' ),
471
								'show'        => true,
472
							)
473
						);
474
						break;
475
476 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...
477
						Give()->notices->register_notice(
478
							array(
479
								'id'          => 'give-reconnect-user',
480
								'type'        => 'updated',
481
								'description' => __( 'User has been successfully connected with Donor.', 'give' ),
482
								'show'        => true,
483
							)
484
						);
485
						break;
486
487 View Code Duplication
					case 'disconnect-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...
488
						Give()->notices->register_notice(
489
							array(
490
								'id'          => 'give-disconnect-user',
491
								'type'        => 'updated',
492
								'description' => __( 'User has been successfully disconnected from donor.', 'give' ),
493
								'show'        => true,
494
							)
495
						);
496
						break;
497
498 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...
499
						Give()->notices->register_notice(
500
							array(
501
								'id'          => 'give-profile-updated',
502
								'type'        => 'updated',
503
								'description' => __( 'Donor information updated successfully.', 'give' ),
504
								'show'        => true,
505
							)
506
						);
507
						break;
508
				}// End switch().
509
			}// End if().
510
		}
511
	}
512
}
513
514
add_action( 'admin_notices', '_give_register_admin_notices', - 1 );
515
516
517
/**
518
 * Display admin bar when active.
519
 *
520
 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
521
 *
522
 * @return bool
523
 */
524
function _give_show_test_mode_notice_in_admin_bar( $wp_admin_bar ) {
525
	$is_test_mode = ! empty( $_POST['test_mode'] ) ?
526
		give_is_setting_enabled( $_POST['test_mode'] ) :
527
		give_is_test_mode();
528
529
	if (
530
		! current_user_can( 'view_give_reports' ) ||
531
		! $is_test_mode
532
	) {
533
		return false;
534
	}
535
536
	// Add the main site admin menu item.
537
	$wp_admin_bar->add_menu(
538
		array(
539
			'id'     => 'give-test-notice',
540
			'href'   => admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=gateways' ),
541
			'parent' => 'top-secondary',
542
			'title'  => __( 'Give Test Mode Active', 'give' ),
543
			'meta'   => array(
544
				'class' => 'give-test-mode-active',
545
			),
546
		)
547
	);
548
549
	return true;
550
}
551
552
add_action( 'admin_bar_menu', '_give_show_test_mode_notice_in_admin_bar', 1000, 1 );
553
554
/**
555
 * Outputs the Give admin bar CSS.
556
 */
557
function _give_test_mode_notice_admin_bar_css() {
558
	if ( ! give_is_test_mode() ) {
559
		return;
560
	}
561
	?>
562
	<style>
563
		#wpadminbar .give-test-mode-active > .ab-item {
564
			color: #fff;
565
			background-color: #ffba00;
566
		}
567
568
		#wpadminbar .give-test-mode-active:hover > .ab-item, #wpadminbar .give-test-mode-active:hover > .ab-item {
569
			background-color: rgba(203, 144, 0, 1) !important;
570
			color: #fff !important;
571
		}
572
	</style>
573
	<?php
574
}
575
576
add_action( 'admin_head', '_give_test_mode_notice_admin_bar_css' );
577
578
579
/**
580
 * Add Link to Import page in from donation archive and donation single page
581
 *
582
 * @since 1.8.13
583
 */
584
function give_import_page_link_callback() {
585
	?>
586
	<a href="<?php echo esc_url( give_import_page_url() ); ?>"
587
	   class="page-import-action page-title-action"><?php _e( 'Import Donations', 'give' ); ?></a>
588
589
	<?php
590
	// Check if view donation single page only.
591
	if ( ! empty( $_REQUEST['view'] ) && 'view-payment-details' === (string) give_clean( $_REQUEST['view'] ) && 'give-payment-history' === give_clean( $_REQUEST['page'] ) ) {
592
		?>
593
		<style type="text/css">
594
			.wrap #transaction-details-heading {
595
				display: inline-block;
596
			}
597
		</style>
598
		<?php
599
	}
600
}
601
602
add_action( 'give_payments_page_top', 'give_import_page_link_callback', 11 );
603
604
/**
605
 * Load donation import ajax callback
606
 * Fire when importing from CSV start
607
 *
608
 * @since  1.8.13
609
 */
610
function give_donation_import_callback() {
611
	// Bailout.
612
	if ( ! current_user_can( 'manage_give_settings' ) ) {
613
		give_die();
614
	}
615
616
	// Disable Give cache
617
	Give_Cache::get_instance()->disable();
618
619
	$import_setting = array();
620
	$fields         = isset( $_POST['fields'] ) ? $_POST['fields'] : null;
621
622
	parse_str( $fields, $output );
623
624
	$import_setting['create_user'] = $output['create_user'];
625
	$import_setting['mode']        = $output['mode'];
626
	$import_setting['delimiter']   = $output['delimiter'];
627
	$import_setting['csv']         = $output['csv'];
628
	$import_setting['delete_csv']  = $output['delete_csv'];
629
	$import_setting['dry_run']     = $output['dry_run'];
630
631
	// Parent key id.
632
	$main_key = maybe_unserialize( $output['main_key'] );
633
634
	$current    = absint( $_REQUEST['current'] );
635
	$total_ajax = absint( $_REQUEST['total_ajax'] );
636
	$start      = absint( $_REQUEST['start'] );
637
	$end        = absint( $_REQUEST['end'] );
638
	$next       = absint( $_REQUEST['next'] );
639
	$total      = absint( $_REQUEST['total'] );
640
	$per_page   = absint( $_REQUEST['per_page'] );
641
	if ( empty( $output['delimiter'] ) ) {
642
		$delimiter = ',';
643
	} else {
644
		$delimiter = $output['delimiter'];
645
	}
646
647
	// Processing done here.
648
	$raw_data                  = give_get_donation_data_from_csv( $output['csv'], $start, $end, $delimiter );
649
	$raw_key                   = maybe_unserialize( $output['mapto'] );
650
	$import_setting['raw_key'] = $raw_key;
651
652
	if ( ! empty( $output['dry_run'] ) ) {
653
		$import_setting['csv_raw_data'] = give_get_donation_data_from_csv( $output['csv'], 1, $end, $delimiter );
654
655
		$import_setting['donors_list'] = Give()->donors->get_donors(
656
			array(
657
				'number' => - 1,
658
				'fields' => array( 'id', 'user_id', 'email' ),
659
			)
660
		);
661
	}
662
663
	// Prevent normal emails.
664
	remove_action( 'give_complete_donation', 'give_trigger_donation_receipt', 999 );
665
	remove_action( 'give_insert_user', 'give_new_user_notification', 10 );
666
	remove_action( 'give_insert_payment', 'give_payment_save_page_data' );
667
668
	$current_key = $start;
669
	foreach ( $raw_data as $row_data ) {
670
		$import_setting['donation_key'] = $current_key;
671
		give_save_import_donation_to_db( $raw_key, $row_data, $main_key, $import_setting );
672
		$current_key ++;
673
	}
674
675
	// Check if function exists or not.
676
	if ( function_exists( 'give_payment_save_page_data' ) ) {
677
		add_action( 'give_insert_payment', 'give_payment_save_page_data' );
678
	}
679
	add_action( 'give_insert_user', 'give_new_user_notification', 10, 2 );
680
	add_action( 'give_complete_donation', 'give_trigger_donation_receipt', 999 );
681
682
	if ( $next == false ) {
683
		$json_data = array(
684
			'success' => true,
685
			'message' => __( 'All donation uploaded successfully!', 'give' ),
686
		);
687
	} else {
688
		$index_start = $start;
689
		$index_end   = $end;
690
		$last        = false;
691
		$next        = true;
692
		if ( $next ) {
693
			$index_start = $index_start + $per_page;
694
			$index_end   = $per_page + ( $index_start - 1 );
695
		}
696
		if ( $index_end >= $total ) {
697
			$index_end = $total;
698
			$last      = true;
699
		}
700
		$json_data = array(
701
			'raw_data' => $raw_data,
702
			'raw_key'  => $raw_key,
703
			'next'     => $next,
704
			'start'    => $index_start,
705
			'end'      => $index_end,
706
			'last'     => $last,
707
		);
708
	}
709
710
	$url              = give_import_page_url(
711
		array(
712
			'step'          => '4',
713
			'importer-type' => 'import_donations',
714
			'csv'           => $output['csv'],
715
			'total'         => $total,
716
			'delete_csv'    => $import_setting['delete_csv'],
717
			'success'       => ( isset( $json_data['success'] ) ? $json_data['success'] : '' ),
718
			'dry_run'       => $output['dry_run'],
719
		)
720
	);
721
	$json_data['url'] = $url;
722
723
	$current ++;
724
	$json_data['current'] = $current;
725
726
	$percentage              = ( 100 / ( $total_ajax + 1 ) ) * $current;
727
	$json_data['percentage'] = $percentage;
728
729
	// Enable Give cache
730
	Give_Cache::get_instance()->enable();
731
732
	$json_data = apply_filters( 'give_import_ajax_responces', $json_data, $fields );
733
	wp_die( json_encode( $json_data ) );
734
}
735
736
add_action( 'wp_ajax_give_donation_import', 'give_donation_import_callback' );
737
738
/**
739
 * Load core settings import ajax callback
740
 * Fire when importing from JSON start
741
 *
742
 * @since  1.8.17
743
 */
744
745
function give_core_settings_import_callback() {
746
	// Bailout.
747
	if ( ! current_user_can( 'manage_give_settings' ) ) {
748
		give_die();
749
	}
750
751
	$fields = isset( $_POST['fields'] ) ? $_POST['fields'] : null;
752
	parse_str( $fields, $fields );
753
754
	$json_data['success'] = false;
755
756
	/**
757
	 * Filter to Modify fields that are being pass by the ajax before importing of the core setting start.
758
	 *
759
	 * @access public
760
	 *
761
	 * @param array $fields
762
	 *
763
	 * @return array $fields
764
	 * @since  1.8.17
765
	 *
766
	 */
767
	$fields = (array) apply_filters( 'give_import_core_settings_fields', $fields );
768
769
	$file_name = ( ! empty( $fields['file_name'] ) ? give_clean( $fields['file_name'] ) : false );
770
771
	if ( ! empty( $file_name ) ) {
772
		$type = ( ! empty( $fields['type'] ) ? give_clean( $fields['type'] ) : 'merge' );
773
774
		// Get the json data from the file and then alter it in array format
775
		$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 769 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...
776
		$json_to_array = json_decode( $json_string, true );
777
778
		// get the current setting from the options table.
779
		$host_give_options = Give_Cache_Setting::get_settings();
780
781
		// Save old settins for backup.
782
		update_option( 'give_settings_old', $host_give_options, false );
783
784
		/**
785
		 * Filter to Modify Core Settings that are being going to get import in options table as give settings.
786
		 *
787
		 * @access public
788
		 *
789
		 * @param array $json_to_array     Setting that are being going to get imported
790
		 * @param array $type              Type of Import
791
		 * @param array $host_give_options Setting old setting that used to be in the options table.
792
		 * @param array $fields            Data that is being send from the ajax
793
		 *
794
		 * @return array $json_to_array Setting that are being going to get imported
795
		 * @since  1.8.17
796
		 *
797
		 */
798
		$json_to_array = (array) apply_filters( 'give_import_core_settings_data', $json_to_array, $type, $host_give_options, $fields );
799
800
		update_option( 'give_settings', $json_to_array, false );
801
802
		$json_data['success'] = true;
803
	}
804
805
	$json_data['percentage'] = 100;
806
807
	/**
808
	 * Filter to Modify core import setting page url
809
	 *
810
	 * @access public
811
	 *
812
	 * @return array $url
813
	 * @since  1.8.17
814
	 *
815
	 */
816
	$json_data['url'] = give_import_page_url(
817
		(array) apply_filters(
818
			'give_import_core_settings_success_url', array(
819
				'step'          => ( empty( $json_data['success'] ) ? '1' : '3' ),
820
				'importer-type' => 'import_core_setting',
821
				'success'       => ( empty( $json_data['success'] ) ? '0' : '1' ),
822
			)
823
		)
824
	);
825
826
	wp_send_json( $json_data );
827
}
828
829
add_action( 'wp_ajax_give_core_settings_import', 'give_core_settings_import_callback' );
830
831
/**
832
 * Initializes blank slate content if a list table is empty.
833
 *
834
 * @since 1.8.13
835
 */
836
function give_blank_slate() {
837
	$blank_slate = new Give_Blank_Slate();
838
	$blank_slate->init();
839
}
840
841
add_action( 'current_screen', 'give_blank_slate' );
842
843
/**
844
 * Validate Fields of User Profile
845
 *
846
 * @param object   $errors Object of WP Errors.
847
 * @param int|bool $update True or False.
848
 * @param object   $user   WP User Data.
849
 *
850
 * @return mixed
851
 * @since 2.0
852
 *
853
 */
854
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...
855
856
	if ( ! empty( $_POST['action'] ) && ( 'adduser' === $_POST['action'] || 'createuser' === $_POST['action'] ) ) {
857
		return;
858
	}
859
860
	if ( ! empty( $user->ID ) ) {
861
		$donor = Give()->donors->get_donor_by( 'user_id', $user->ID );
862
863
		if ( $donor ) {
864
			// If Donor is attached with User, then validate first name.
865
			if ( empty( $_POST['first_name'] ) ) {
866
				$errors->add(
867
					'empty_first_name',
868
					sprintf(
869
						'<strong>%1$s:</strong> %2$s',
870
						__( 'ERROR', 'give' ),
871
						__( 'Please enter your first name.', 'give' )
872
					)
873
				);
874
			}
875
		}
876
	}
877
878
}
879
880
add_action( 'user_profile_update_errors', 'give_validate_user_profile', 10, 3 );
881
882
/**
883
 * Show Donor Information on User Profile Page.
884
 *
885
 * @param object $user User Object.
886
 *
887
 * @since 2.0
888
 */
889
function give_donor_information_profile_fields( $user ) {
890
	$donor = Give()->donors->get_donor_by( 'user_id', $user->ID );
891
892
	// Display Donor Information, only if donor is attached with User.
893
	if ( ! empty( $donor->user_id ) ) {
894
		?>
895
		<table class="form-table">
896
			<tbody>
897
			<tr>
898
				<th scope="row"><?php _e( 'Donor', 'give' ); ?></th>
899
				<td>
900
					<a href="<?php echo admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ); ?>">
901
						<?php _e( 'View Donor Information', 'give' ); ?>
902
					</a>
903
				</td>
904
			</tr>
905
			</tbody>
906
		</table>
907
		<?php
908
	}
909
}
910
911
add_action( 'personal_options', 'give_donor_information_profile_fields' );
912
/**
913
 * Get Array of WP User Roles.
914
 *
915
 * @return array
916
 * @since 1.8.13
917
 *
918
 */
919
function give_get_user_roles() {
920
	$user_roles = array();
921
922
	// Loop through User Roles.
923
	foreach ( get_editable_roles() as $role_name => $role_info ) :
924
		$user_roles[ $role_name ] = $role_info['name'];
925
	endforeach;
926
927
	return $user_roles;
928
}
929
930
931
/**
932
 * Ajax handle for donor address.
933
 *
934
 * @return string
935
 * @since 2.0
936
 *
937
 */
938
function __give_ajax_donor_manage_addresses() {
939
	// Bailout.
940
	if (
941
		empty( $_POST['form'] ) ||
942
		empty( $_POST['donorID'] )
943
	) {
944
		wp_send_json_error(
945
			array(
946
				'error' => 1,
947
			)
948
		);
949
	}
950
951
	$post                  = give_clean( wp_parse_args( $_POST ) );
952
	$donorID               = absint( $post['donorID'] );
953
	$form_data             = give_clean( wp_parse_args( $post['form'] ) );
954
	$is_multi_address_type = ( 'billing' === $form_data['address-id'] || false !== strpos( $form_data['address-id'], '_' ) );
955
	$exploded_address_id   = explode( '_', $form_data['address-id'] );
956
	$address_type          = false !== strpos( $form_data['address-id'], '_' ) ?
957
		array_shift( $exploded_address_id ) :
958
		$form_data['address-id'];
959
	$address_id            = false !== strpos( $form_data['address-id'], '_' ) ?
960
		array_pop( $exploded_address_id ) :
961
		null;
962
	$response_data         = array(
963
		'action' => $form_data['address-action'],
964
		'id'     => $form_data['address-id'],
965
	);
966
967
	// Security check.
968 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...
969
		wp_send_json_error(
970
			array(
971
				'error'     => 1,
972
				'error_msg' => wp_sprintf(
973
					'<div class="notice notice-error"><p>%s</p></div>',
974
					__( 'Error: Security issue.', 'give' )
975
				),
976
			)
977
		);
978
	}
979
980
	$donor = new Give_Donor( $donorID );
981
982
	// Verify donor.
983
	if ( ! $donor->id ) {
984
		wp_send_json_error(
985
			array(
986
				'error' => 3,
987
			)
988
		);
989
	}
990
991
	// Unset all data except address.
992
	unset(
993
		$form_data['_wpnonce'],
994
		$form_data['address-action'],
995
		$form_data['address-id']
996
	);
997
998
	// Process action.
999
	switch ( $response_data['action'] ) {
1000
1001
		case 'add':
1002 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 953 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...
1003
				wp_send_json_error(
1004
					array(
1005
						'error'     => 1,
1006
						'error_msg' => wp_sprintf(
1007
							'<div class="notice notice-error"><p>%s</p></div>',
1008
							__( 'Error: Unable to save the address. Please check if address already exist.', 'give' )
1009
						),
1010
					)
1011
				);
1012
			}
1013
1014
			$total_addresses = count( $donor->address[ $address_type ] );
1015
1016
			$address_index = $is_multi_address_type ?
1017
				$total_addresses - 1 :
1018
				$address_type;
1019
1020
			$array_keys = array_keys( $donor->address[ $address_type ] );
1021
1022
			$address_id = $is_multi_address_type ?
1023
				end( $array_keys ) :
1024
				$address_type;
1025
1026
			$response_data['address_html'] = __give_get_format_address(
1027
				end( $donor->address['billing'] ),
1028
				array(
1029
					// We can add only billing address from donor screen.
1030
					'type'  => 'billing',
1031
					'id'    => $address_id,
1032
					'index' => ++ $address_index,
1033
				)
1034
			);
1035
			$response_data['success_msg']  = wp_sprintf(
1036
				'<div class="notice updated"><p>%s</p></div>',
1037
				__( 'Successfully added a new address to the donor.', 'give' )
1038
			);
1039
1040
			if ( $is_multi_address_type ) {
1041
				$response_data['id'] = "{$response_data['id']}_{$address_index}";
1042
			}
1043
1044
			break;
1045
1046
		case 'remove':
1047 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...
1048
				wp_send_json_error(
1049
					array(
1050
						'error'     => 2,
1051
						'error_msg' => wp_sprintf(
1052
							'<div class="notice notice-error"><p>%s</p></div>',
1053
							__( 'Error: Unable to delete address.', 'give' )
1054
						),
1055
					)
1056
				);
1057
			}
1058
1059
			$response_data['success_msg'] = wp_sprintf(
1060
				'<div class="notice updated"><p>%s</p></div>',
1061
				__( 'Successfully removed a address of donor.', 'give' )
1062
			);
1063
1064
			break;
1065
1066
		case 'update':
1067 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 953 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...
1068
				wp_send_json_error(
1069
					array(
1070
						'error'     => 3,
1071
						'error_msg' => wp_sprintf(
1072
							'<div class="notice notice-error"><p>%s</p></div>',
1073
							__( 'Error: Unable to update address. Please check if address already exist.', 'give' )
1074
						),
1075
					)
1076
				);
1077
			}
1078
1079
			$response_data['address_html'] = __give_get_format_address(
1080
				$is_multi_address_type ?
1081
					$donor->address[ $address_type ][ $address_id ] :
1082
					$donor->address[ $address_type ],
1083
				array(
1084
					'type'  => $address_type,
1085
					'id'    => $address_id,
1086
					'index' => $address_id,
1087
				)
1088
			);
1089
			$response_data['success_msg']  = wp_sprintf(
1090
				'<div class="notice updated"><p>%s</p></div>',
1091
				__( 'Successfully updated a address of donor', 'give' )
1092
			);
1093
1094
			break;
1095
	}// End switch().
1096
1097
	wp_send_json_success( $response_data );
1098
}
1099
1100
add_action( 'wp_ajax_donor_manage_addresses', '__give_ajax_donor_manage_addresses' );
1101
1102
/**
1103
 * Admin donor billing address label
1104
 *
1105
 * @param string $address_label
1106
 *
1107
 * @return string
1108
 * @since 2.0
1109
 *
1110
 */
1111
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...
1112
	$address_label = __( 'Billing Address', 'give' );
1113
1114
	return $address_label;
1115
}
1116
1117
add_action( 'give_donor_billing_address_label', '__give_donor_billing_address_label' );
1118
1119
/**
1120
 * Admin donor personal address label
1121
 *
1122
 * @param string $address_label
1123
 *
1124
 * @return string
1125
 * @since 2.0
1126
 *
1127
 */
1128
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...
1129
	$address_label = __( 'Personal Address', 'give' );
1130
1131
	return $address_label;
1132
}
1133
1134
add_action( 'give_donor_personal_address_label', '__give_donor_personal_address_label' );
1135
1136
/**
1137
 * Update Donor Information when User Profile is updated from admin.
1138
 * Note: for internal use only.
1139
 *
1140
 * @param int $user_id
1141
 *
1142
 * @access public
1143
 * @return bool
1144
 * @since  2.0
1145
 *
1146
 */
1147
function give_update_donor_name_on_user_update( $user_id = 0 ) {
1148
1149
	if ( current_user_can( 'edit_user', $user_id ) ) {
1150
1151
		$donor = new Give_Donor( $user_id, true );
1152
1153
		// Bailout, if donor doesn't exists.
1154
		if ( ! $donor ) {
1155
			return false;
1156
		}
1157
1158
		// Get User First name and Last name.
1159
		$first_name = ( $_POST['first_name'] ) ? give_clean( $_POST['first_name'] ) : get_user_meta( $user_id, 'first_name', true );
1160
		$last_name  = ( $_POST['last_name'] ) ? give_clean( $_POST['last_name'] ) : get_user_meta( $user_id, 'last_name', true );
1161
		$full_name  = strip_tags( wp_unslash( trim( "{$first_name} {$last_name}" ) ) );
1162
1163
		// Assign User First name and Last name to Donor.
1164
		Give()->donors->update(
1165
			$donor->id, array(
1166
				'name' => $full_name,
1167
			)
1168
		);
1169
		Give()->donor_meta->update_meta( $donor->id, '_give_donor_first_name', $first_name );
1170
		Give()->donor_meta->update_meta( $donor->id, '_give_donor_last_name', $last_name );
1171
1172
	}
1173
}
1174
1175
add_action( 'edit_user_profile_update', 'give_update_donor_name_on_user_update', 10 );
1176
add_action( 'personal_options_update', 'give_update_donor_name_on_user_update', 10 );
1177
1178
1179
/**
1180
 * Updates the email address of a donor record when the email on a user is updated
1181
 * Note: for internal use only.
1182
 *
1183
 * @param int          $user_id       User ID.
1184
 * @param WP_User|bool $old_user_data User data.
1185
 *
1186
 * @return bool
1187
 * @since  1.4.3
1188
 * @access public
1189
 *
1190
 */
1191
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...
1192
1193
	$donor = new Give_Donor( $user_id, true );
1194
1195
	if ( ! $donor ) {
1196
		return false;
1197
	}
1198
1199
	$user = get_userdata( $user_id );
1200
1201
	if ( ! empty( $user ) && $user->user_email !== $donor->email ) {
1202
1203
		$success = Give()->donors->update(
1204
			$donor->id, array(
1205
				'email' => $user->user_email,
1206
			)
1207
		);
1208
1209
		if ( $success ) {
1210
			// Update some payment meta if we need to
1211
			$payments_array = explode( ',', $donor->payment_ids );
1212
1213
			if ( ! empty( $payments_array ) ) {
1214
1215
				foreach ( $payments_array as $payment_id ) {
1216
1217
					give_update_payment_meta( $payment_id, 'email', $user->user_email );
1218
1219
				}
1220
			}
1221
1222
			/**
1223
			 * Fires after updating donor email on user update.
1224
			 *
1225
			 * @param WP_User    $user  WordPress User object.
1226
			 * @param Give_Donor $donor Give donor object.
1227
			 *
1228
			 * @since 1.4.3
1229
			 *
1230
			 */
1231
			do_action( 'give_update_donor_email_on_user_update', $user, $donor );
1232
1233
		}
1234
	}
1235
1236
}
1237
1238
add_action( 'profile_update', 'give_update_donor_email_on_user_update', 10, 2 );
1239
1240
1241
/**
1242
 * Flushes Give's cache.
1243
 */
1244
function give_cache_flush() {
1245
	if ( ! current_user_can( 'manage_give_settings' ) ) {
1246
		wp_die();
1247
	}
1248
1249
	$result = Give_Cache::flush_cache();
1250
1251
	if ( $result ) {
1252
		wp_send_json_success(
1253
			array(
1254
				'message' => __( 'Cache flushed successfully.', 'give' ),
1255
			)
1256
		);
1257
	} else {
1258
		wp_send_json_error(
1259
			array(
1260
				'message' => __( 'An error occurred while flushing the cache.', 'give' ),
1261
			)
1262
		);
1263
	}
1264
}
1265
1266
add_action( 'wp_ajax_give_cache_flush', 'give_cache_flush', 10, 0 );
1267
1268
/**
1269
 * Admin notices for errors
1270
 * note: only for internal use
1271
 *
1272
 * @access public
1273
 * @return void
1274
 * @since  2.5.0
1275
 */
1276
function give_license_notices() {
1277
1278
	if ( ! current_user_can( 'manage_give_settings' ) ) {
1279
		return;
1280
	}
1281
1282
	// Do not show licenses notices on license tab.
1283
	if ( Give_Admin_Settings::is_setting_page( 'licenses' ) ) {
1284
		return;
1285
	}
1286
1287
	$give_plugins          = give_get_plugins( array( 'only_premium_add_ons' => true ) );
1288
	$give_licenses         = get_option( 'give_licenses', array() );
1289
	$notice_data           = array();
1290
	$license_data          = array();
1291
	$invalid_license_count = 0;
1292
	$addons_with_license   = array();
1293
1294
	// Loop through Give licenses to find license status.
1295
	foreach ( $give_licenses as $key => $give_license ) {
1296
		if ( empty( $license_data[ $give_license['license'] ] ) ) {
1297
			$license_data[ $give_license['license'] ] = array(
1298
				'count'   => 0,
1299
				'add-ons' => array(),
1300
			);
1301
		}
1302
1303
		// Setup data for all access pass.
1304
		if ( $give_license['is_all_access_pass'] ) {
1305
			$addons_list = wp_list_pluck( $give_license['download'], 'plugin_slug' );
1306
			foreach ( $addons_list as $item ) {
1307
				$license_data[ $give_license['license'] ]['add-ons'][] = $addons_with_license[] = $item;
1308
			}
1309
		} else {
1310
			$license_data[ $give_license['license'] ]['add-ons'][] = $addons_with_license[] = $give_license['plugin_slug'];
1311
		}
1312
1313
		$license_data[ $give_license['license'] ]['count'] += 1;
1314
	}
1315
1316
	// Set data for inactive add-ons.
1317
	$inactive_addons = array_diff( wp_list_pluck( $give_plugins, 'Dir' ), $addons_with_license );
1318
1319
	$license_data['inactive'] = array(
1320
		'count'   => count( $inactive_addons ),
1321
		'add-ons' => array_values( $inactive_addons ),
1322
	);
1323
1324
	// Unset active license add-ons as not required.
1325
	unset( $license_data['valid'] );
1326
1327
	// Combine site inactive with inactive and unset site_inactive because already merged information with inactive
1328
	if ( ! empty( $license_data['site_inactive'] ) ) {
1329
		$license_data['inactive']['count']   += $license_data['site_inactive']['count'];
1330
		$license_data['inactive']['add-ons'] += $license_data['site_inactive']['add-ons'];
1331
1332
		unset( $license_data['site_inactive'] );
1333
	}
1334
1335
	// Loop through license data.
1336
	foreach ( $license_data as $key => $license ) {
1337
		if ( ! $license['count'] ) {
1338
			continue;
1339
		}
1340
1341
		$notice_data[ $key ] = sprintf(
1342
			'%1$s %2$s',
1343
			$license['count'],
1344
			$key
1345
		);
1346
1347
		// This will contain sum of count expect license with valid status.
1348
		$invalid_license_count += $license['count'];
1349
	}
1350
1351
	// Prepare license notice description.
1352
	$prepared_notice_status = implode( ' , ', $notice_data );
1353
	$prepared_notice_status = 2 <= count( $notice_data )
1354
		? substr_replace( $prepared_notice_status, 'and', strrpos( $prepared_notice_status, ',' ), 1 )
1355
		: $prepared_notice_status;
1356
1357
	$notice_description = sprintf(
1358
		_n(
1359
			'Your GiveWP add-on is not receiving critical updates and new features because you have %1$s license key. Please <a href="%2$s" title="%3$s">activate your license</a> to receive updates and <a href="%4$s" target="_blank" title="%5$s">priority support</a>',
1360
			'Your GiveWP add-ons are not receiving critical updates and new features because you have %1$s license keys. Please <a href="%2$s" title="%3$s">activate your license</a> to receive updates and <a href="%4$s" target="_blank" title="%5$s">priority support</a>',
1361
			$invalid_license_count,
1362
			'give'
1363
		),
1364
		$prepared_notice_status,
1365
		admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=licenses' ),
1366
		__( 'Activate License', 'give' ),
1367
		esc_url( 'https://givewp.com/priority-support/' ),
1368
		__( 'Priority Support', 'give' )
1369
	);
1370
1371
	// Check by add-on if any give add-on activated without license.
1372
	// Do not show this notice if add-on activated with in 3 days.
1373
	$is_required_days_past = current_time( 'timestamp' ) > ( Give_Cache_Setting::get_option( 'give_addon_last_activated' ) + ( 3 * DAY_IN_SECONDS ) );
1374
1375
	// Default license notice arguments.
1376
	$license_notice_args = array(
1377
		'id'               => 'give-invalid-expired-license',
1378
		'type'             => 'error',
1379
		'description'      => $notice_description,
1380
		'dismissible_type' => 'user',
1381
		'dismiss_interval' => 'shortly',
1382
	);
1383
1384
	// Register Notices.
1385
	if ( $invalid_license_count && $is_required_days_past ) {
1386
		Give()->notices->register_notice( $license_notice_args );
1387
	}
1388
}
1389
1390
add_action( 'admin_notices', 'give_license_notices' );
1391
1392
1393
/**
1394
 * Log give addon activation time
1395
 *
1396
 * @param $plugin
1397
 * @param $network_wide
1398
 *
1399
 * @since 2.5.0
1400
 */
1401
function give_log_addon_activation_time( $plugin, $network_wide ) {
1402
	if ( $network_wide ) {
1403
		return;
1404
	}
1405
1406
	$plugin_data = give_get_plugins( array( 'only_premium_add_ons' => true ) );
1407
	$plugin_data = ! empty( $plugin_data[ $plugin ] ) ? $plugin_data[ $plugin ] : array();
1408
1409
	if ( $plugin_data ) {
1410
		update_option( 'give_addon_last_activated', current_time( 'timestamp' ), 'no' );
1411
	}
1412
}
1413
1414
add_action( 'activate_plugin', 'give_log_addon_activation_time', 10, 2 );
1415
1416
1417
/**
1418
 * Hide all admin notice from add-ons page
1419
 *
1420
 * Note: only for internal use
1421
 *
1422
 * @since 2.5.0
1423
 */
1424
function give_hide_notices_on_add_ons_page() {
1425
	$page = ! empty( $_GET['page'] ) ? give_clean( $_GET['page'] ) : '';
1426
1427
	// Bailout.
1428
	if ( 'give-addons' !== $page ) {
1429
		return;
1430
	}
1431
1432
	remove_all_actions( 'admin_notices' );
1433
}
1434
1435
add_action( 'in_admin_header', 'give_hide_notices_on_add_ons_page', 999 );
1436
1437
1438
/**
1439
 * Admin JS
1440
 *
1441
 * @since 2.5.0
1442
 */
1443
function give_admin_quick_js() {
1444
	if ( is_multisite() && is_blog_admin() ) {
1445
		?>
1446
		<script>
1447
			jQuery( document ).ready( function( $ ) {
1448
				var $updateNotices = $( '[id$="-update"] ', '.wp-list-table' );
1449
1450
				if ( $updateNotices.length ) {
1451
					$.each( $updateNotices, function( index, $updateNotice ) {
1452
						$updateNotice = $( $updateNotice );
1453
						$updateNotice.prev().addClass( 'update' );
1454
					} );
1455
				}
1456
			} );
1457
		</script>
1458
		<?php
1459
	}
1460
}
1461
1462
add_action( 'admin_head', 'give_admin_quick_js' );
1463
1464
1465