PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.16.9
GiveWP – Donation Plugin and Fundraising Platform v4.16.9
4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 All 255 releases
← All changes | includes/admin/admin-actions.php +914 -359 2.3.14.16.9 View file →
@@ -1,13 +1,18 @@
1 1 <?php
2 +
3 +use Give\Framework\Database\DB;
4 +use Give\Helpers\Utils;
5 +use Give\Log\ValueObjects\LogType;
6 +
2 7 /**
3 8 * Admin Actions
4 9 *
5 10 * @package Give
6 - * @subpackage Admin/Actions
11 + * @since 1.0
7 12 * @copyright Copyright (c) 2016, GiveWP
8 13 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 - * @since 1.0
14 + * @subpackage Admin/Actions
10 15 */
11 16
12 17 // Exit if accessed directly.
13 18 if ( ! defined( 'ABSPATH' ) ) {
@@ -19,16 +24,16 @@
19 24 *
20 25 * @since 1.8
21 26 */
22 27 function give_load_wp_editor() {
23 - if ( ! isset( $_POST['wp_editor'] ) ) {
28 + if ( ! isset( $_POST['wp_editor'] ) || ! current_user_can( 'edit_give_forms' ) ) {
24 29 die();
25 30 }
26 31
27 32 $wp_editor = json_decode( base64_decode( $_POST['wp_editor'] ), true );
28 - $wp_editor[2]['textarea_name'] = $_POST['textarea_name'];
33 + $wp_editor[2]['textarea_name'] = give_clean( $_POST['textarea_name'] );
29 34
30 - wp_editor( $wp_editor[0], $_POST['wp_editor_id'], $wp_editor[2] );
35 + wp_editor( wp_kses_post( $wp_editor[0] ), give_clean( $_POST['wp_editor_id'] ), $wp_editor[2] );
31 36
32 37 die();
33 38 }
34 39
@@ -37,20 +42,21 @@
37 42
38 43 /**
39 44 * Redirect admin to clean url give admin pages.
40 45 *
41 - * @since 1.8
46 + * @since 2.25.2 Removed _wpnonce from list of removed args.
47 + * @since 1.8
42 48 *
43 49 * @return bool
44 50 */
45 51 function give_redirect_to_clean_url_admin_pages() {
46 52 // Give admin pages.
47 - $give_pages = array(
53 + $give_pages = [
48 54 'give-payment-history',
49 55 'give-donors',
50 56 'give-reports',
51 57 'give-tools',
52 - );
58 + ];
53 59
54 60 // Get current page.
55 61 $current_page = isset( $_GET['page'] ) ? esc_attr( $_GET['page'] ) : '';
56 62
@@ -72,12 +78,14 @@
72 78
73 79 if ( $redirect ) {
74 80 // Redirect.
75 81 wp_redirect(
76 - remove_query_arg(
77 - array( '_wp_http_referer', '_wpnonce' ),
78 - wp_unslash( $_SERVER['REQUEST_URI'] )
79 - )
82 + esc_url_raw(
83 + remove_query_arg(
84 + ['_wp_http_referer'],
85 + wp_unslash($_SERVER['REQUEST_URI'])
86 + )
87 + )
80 88 );
81 89 exit;
82 90 }
83 91 }
@@ -90,14 +98,13 @@
90 98 *
91 99 * This code is used with AJAX call to hide outdated PHP notice for a short period of time
92 100 *
93 101 * @since 1.8.9
94 - *
95 102 * @return void
96 103 */
97 104 function give_hide_outdated_php_notice() {
98 105
99 - if ( ! isset( $_POST['_give_hide_outdated_php_notices_shortly'] ) ) {
106 + if ( ! isset( $_POST['_give_hide_outdated_php_notices_shortly'] ) || ! current_user_can( 'manage_give_settings' ) ) {
100 107 give_die();
101 108 }
102 109
103 110 // Transient key name.
@@ -118,9 +125,10 @@
118 125
119 126 /**
120 127 * Register admin notices.
121 128 *
122 - * @since 1.8.9
129 + * @since 2.25.2 Add nonce check for bulk action.
130 + * @since 1.8.9
123 131 */
124 132 function _give_register_admin_notices() {
125 133 // Bailout.
126 134 if ( ! is_admin() ) {
@@ -134,70 +142,79 @@
134 142 ) {
135 143
136 144 // Add payment bulk notice.
137 145 if (
138 - current_user_can( 'edit_give_payments' ) &&
139 - isset( $_GET['payment'] ) &&
140 - ! empty( $_GET['payment'] )
146 + current_user_can('edit_give_payments') &&
147 + isset($_GET['_wpnonce']) &&
148 + wp_verify_nonce($_GET['_wpnonce'], 'bulk-forms') &&
149 + isset($_GET['payment']) &&
150 + ! empty( $_GET['payment'] )
141 151 ) {
142 152 $payment_count = isset( $_GET['payment'] ) ? count( $_GET['payment'] ) : 0;
143 153
144 154 switch ( $_GET['action'] ) {
145 155 case 'delete':
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'
156 + Give()->notices->register_notice(
157 + [
158 + 'id' => 'bulk_action_delete',
159 + 'type' => 'updated',
160 + 'description' => sprintf(
161 + _n(
162 + 'Successfully deleted one donation.',
163 + 'Successfully deleted %d donations.',
164 + $payment_count,
165 + 'give'
166 + ),
167 + $payment_count
155 168 ),
156 - $payment_count ),
157 - 'show' => true,
158 - ) );
169 + 'show' => true,
170 + ]
171 + );
159 172
160 173 break;
161 174
162 175 case 'resend-receipt':
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.',
176 + Give()->notices->register_notice(
177 + [
178 + 'id' => 'bulk_action_resend_receipt',
179 + 'type' => 'updated',
180 + 'description' => sprintf(
181 + _n(
182 + 'Successfully sent email receipt to one recipient.',
183 + 'Successfully sent email receipts to %d recipients.',
184 + $payment_count,
185 + 'give'
186 + ),
187 + $payment_count
188 + ),
189 + 'show' => true,
190 + ]
191 + );
192 + break;
193 +
194 + case 'set-status-publish':
195 + case 'set-status-pending':
196 + case 'set-status-processing':
197 + case 'set-status-refunded':
198 + case 'set-status-revoked':
199 + case 'set-status-failed':
200 + case 'set-status-cancelled':
201 + case 'set-status-abandoned':
202 + case 'set-status-preapproval':
203 + Give()->notices->register_notice(
204 + [
205 + 'id' => 'bulk_action_status_change',
206 + 'type' => 'updated',
207 + 'description' => _n(
208 + 'Donation status updated successfully.',
209 + 'Donation statuses updated successfully.',
170 210 $payment_count,
171 211 'give'
172 212 ),
173 - $payment_count
174 - ),
175 - 'show' => true,
176 - ) );
213 + 'show' => true,
214 + ]
215 + );
177 216 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 - case 'set-status-preapproval' :
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 217 }// End switch().
201 218 }// End if().
202 219 }// End if().
203 220
@@ -207,39 +224,47 @@
207 224 foreach ( $message_notices as $message_notice ) {
208 225 // Donation reports errors.
209 226 if ( current_user_can( 'view_give_reports' ) ) {
210 227 switch ( $message_notice ) {
211 - case 'donation-deleted' :
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 - ) );
228 + case 'donation-deleted':
229 + Give()->notices->register_notice(
230 + [
231 + 'id' => 'give-donation-deleted',
232 + 'type' => 'updated',
233 + 'description' => __( 'The donation has been deleted.', 'give' ),
234 + 'show' => true,
235 + ]
236 + );
218 237 break;
219 - case 'email-sent' :
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 - ) );
238 + case 'email-sent':
239 + Give()->notices->register_notice(
240 + [
241 + 'id' => 'give-email-sent',
242 + 'type' => 'updated',
243 + 'description' => __( 'The donation receipt has been resent.', 'give' ),
244 + 'show' => true,
245 + ]
246 + );
226 247 break;
227 - case 'refreshed-reports' :
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 - ) );
248 + case 'refreshed-reports':
249 + Give()->notices->register_notice(
250 + [
251 + 'id' => 'give-refreshed-reports',
252 + 'type' => 'updated',
253 + 'description' => __( 'The reports cache has been cleared.', 'give' ),
254 + 'show' => true,
255 + ]
256 + );
234 257 break;
235 - case 'donation-note-deleted' :
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 - ) );
258 + case 'donation-note-deleted':
259 + Give()->notices->register_notice(
260 + [
261 + 'id' => 'give-donation-note-deleted',
262 + 'type' => 'updated',
263 + 'description' => __( 'The donation note has been deleted.', 'give' ),
264 + 'show' => true,
265 + ]
266 + );
242 267 break;
243 268 }// End switch().
244 269 }// End if().
245 270
@@ -245,64 +270,89 @@
245 270
246 271 // Give settings notices and errors.
247 272 if ( current_user_can( 'manage_give_settings' ) ) {
248 273 switch ( $message_notice ) {
249 - case 'settings-imported' :
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 - ) );
274 + case 'settings-imported':
275 + Give()->notices->register_notice(
276 + [
277 + 'id' => 'give-settings-imported',
278 + 'type' => 'updated',
279 + 'description' => __( 'The settings have been imported.', 'give' ),
280 + 'show' => true,
281 + ]
282 + );
256 283 break;
257 - case 'api-key-generated' :
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 - ) );
284 + case 'api-key-generated':
285 + Give()->notices->register_notice(
286 + [
287 + 'id' => 'give-api-key-generated',
288 + 'type' => 'updated',
289 + 'description' => __( 'API keys have been generated.', 'give' ),
290 + 'show' => true,
291 + ]
292 + );
264 293 break;
265 - case 'api-key-exists' :
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 - ) );
294 + case 'api-key-exists':
295 + Give()->notices->register_notice(
296 + [
297 + 'id' => 'give-api-key-exists',
298 + 'type' => 'updated',
299 + 'description' => __( 'The specified user already has API keys.', 'give' ),
300 + 'show' => true,
301 + ]
302 + );
272 303 break;
273 - case 'api-key-regenerated' :
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 - ) );
304 + case 'api-key-regenerated':
305 + Give()->notices->register_notice(
306 + [
307 + 'id' => 'give-api-key-regenerated',
308 + 'type' => 'updated',
309 + 'description' => __( 'API keys have been regenerated.', 'give' ),
310 + 'show' => true,
311 + ]
312 + );
280 313 break;
281 - case 'api-key-revoked' :
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 - ) );
314 + case 'api-key-revoked':
315 + Give()->notices->register_notice(
316 + [
317 + 'id' => 'give-api-key-revoked',
318 + 'type' => 'updated',
319 + 'description' => __( 'API keys have been revoked.', 'give' ),
320 + 'show' => true,
321 + ]
322 + );
288 323 break;
289 - case 'sent-test-email' :
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 - ) );
324 + case 'sent-test-email':
325 + Give()->notices->register_notice(
326 + [
327 + 'id' => 'give-sent-test-email',
328 + 'type' => 'updated',
329 + 'description' => sprintf( __( 'The test email has been sent to %s.', 'give' ), wp_get_current_user()->user_email ),
330 + 'show' => true,
331 + ]
332 + );
296 333 break;
297 334 case 'matched-success-failure-page':
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 - ) );
335 + Give()->notices->register_notice(
336 + [
337 + 'id' => 'give-matched-success-failure-page',
338 + 'type' => 'updated',
339 + 'description' => __( 'You cannot set the success and failed pages to the same page', 'give' ),
340 + 'show' => true,
341 + ]
342 + );
304 343 break;
344 + case 'akismet-deblacklisted-email':
345 + Give()->notices->register_notice(
346 + [
347 + 'id' => 'give-akismet-deblacklisted-email',
348 + 'type' => 'updated',
349 + 'description' => __( 'Email de-blacklisted successfully. Now Donor will able to process donation with email flagged as spam', 'give' ),
350 + 'show' => true,
351 + 'dismissible' => 'auto',
352 + ]
353 + );
354 + break;
305 355 }// End switch().
306 356 }// End if().
307 357
308 358 // Payments errors.
@@ -307,23 +357,27 @@
307 357
308 358 // Payments errors.
309 359 if ( current_user_can( 'edit_give_payments' ) ) {
310 360 switch ( $message_notice ) {
311 - case 'note-added' :
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 - ) );
361 + case 'note-added':
362 + Give()->notices->register_notice(
363 + [
364 + 'id' => 'give-note-added',
365 + 'type' => 'updated',
366 + 'description' => __( 'The donation note has been added.', 'give' ),
367 + 'show' => true,
368 + ]
369 + );
318 370 break;
319 - case 'payment-updated' :
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 - ) );
371 + case 'payment-updated':
372 + Give()->notices->register_notice(
373 + [
374 + 'id' => 'give-payment-updated',
375 + 'type' => 'updated',
376 + 'description' => __( 'The donation has been updated.', 'give' ),
377 + 'show' => true,
378 + ]
379 + );
326 380 break;
327 381 }// End switch().
328 382 }// End if().
329 383
@@ -329,119 +383,194 @@
329 383
330 384 // Donor Notices.
331 385 if ( current_user_can( 'edit_give_payments' ) ) {
332 386 switch ( $message_notice ) {
333 - case 'donor-deleted' :
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 - ) );
387 + case 'donor-deleted':
388 + Give()->notices->register_notice(
389 + [
390 + 'id' => 'give-donor-deleted',
391 + 'type' => 'updated',
392 + 'description' => __( 'The selected donor(s) has been deleted.', 'give' ),
393 + 'show' => true,
394 + ]
395 + );
340 396 break;
341 397
342 - case 'donor-donations-deleted' :
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 - ) );
398 + case 'donor-donations-deleted':
399 + Give()->notices->register_notice(
400 + [
401 + 'id' => 'give-donor-donations-deleted',
402 + 'type' => 'updated',
403 + 'description' => __( 'The selected donor(s) and the associated donation(s) has been deleted.', 'give' ),
404 + 'show' => true,
405 + ]
406 + );
349 407 break;
350 408
351 - case 'confirm-delete-donor' :
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 - ) );
409 + case 'confirm-delete-donor':
410 + Give()->notices->register_notice(
411 + [
412 + 'id' => 'give-confirm-delete-donor',
413 + 'type' => 'updated',
414 + 'description' => __( 'You must confirm to delete the selected donor(s).', 'give' ),
415 + 'show' => true,
416 + ]
417 + );
358 418 break;
359 419
360 - case 'invalid-donor-id' :
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 - ) );
420 + case 'invalid-donor-id':
421 + Give()->notices->register_notice(
422 + [
423 + 'id' => 'give-invalid-donor-id',
424 + 'type' => 'updated',
425 + 'description' => __( 'Invalid Donor ID.', 'give' ),
426 + 'show' => true,
427 + ]
428 + );
367 429 break;
368 430
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 - ) );
431 + case 'donor-delete-failed':
432 + Give()->notices->register_notice(
433 + [
434 + 'id' => 'give-donor-delete-failed',
435 + 'type' => 'error',
436 + 'description' => __( 'Unable to delete selected donor(s).', 'give' ),
437 + 'show' => true,
438 + ]
439 + );
376 440 break;
377 441
378 - case 'email-added' :
379 - Give()->notices->register_notice( array(
380 - 'id' => 'give-email-added',
381 - 'type' => 'updated',
382 - 'description' => __( 'Donor email added.', 'give' ),
383 - 'show' => true,
384 - ) );
442 + case 'email-added':
443 + Give()->notices->register_notice(
444 + [
445 + 'id' => 'give-email-added',
446 + 'type' => 'updated',
447 + 'description' => __( 'Donor email added.', 'give' ),
448 + 'show' => true,
449 + ]
450 + );
385 451 break;
386 452
387 - case 'email-removed' :
388 - Give()->notices->register_notice( array(
389 - 'id' => 'give-email-removed',
390 - 'type' => 'updated',
391 - 'description' => __( 'Donor email removed.', 'give' ),
392 - 'show' => true,
393 - ) );
453 + case 'email-removed':
454 + Give()->notices->register_notice(
455 + [
456 + 'id' => 'give-email-removed',
457 + 'type' => 'updated',
458 + 'description' => __( 'Donor email removed.', 'give' ),
459 + 'show' => true,
460 + ]
461 + );
394 462 break;
395 463
396 - case 'email-remove-failed' :
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 - ) );
464 + case 'email-remove-failed':
465 + Give()->notices->register_notice(
466 + [
467 + 'id' => 'give-email-remove-failed',
468 + 'type' => 'updated',
469 + 'description' => __( 'Failed to remove donor email.', 'give' ),
470 + 'show' => true,
471 + ]
472 + );
403 473 break;
404 474
405 - case 'primary-email-updated' :
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 - ) );
475 + case 'primary-email-updated':
476 + Give()->notices->register_notice(
477 + [
478 + 'id' => 'give-primary-email-updated',
479 + 'type' => 'updated',
480 + 'description' => __( 'Primary email updated for donor.', 'give' ),
481 + 'show' => true,
482 + ]
483 + );
412 484 break;
413 485
414 - case 'primary-email-failed' :
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 - ) );
486 + case 'primary-email-failed':
487 + Give()->notices->register_notice(
488 + [
489 + 'id' => 'give-primary-email-failed',
490 + 'type' => 'updated',
491 + 'description' => __( 'Failed to set primary email.', 'give' ),
492 + 'show' => true,
493 + ]
494 + );
421 495 break;
422 496
423 - case 'reconnect-user' :
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 - ) );
497 + case 'reconnect-user':
498 + Give()->notices->register_notice(
499 + [
500 + 'id' => 'give-reconnect-user',
501 + 'type' => 'updated',
502 + 'description' => __( 'User has been successfully connected with Donor.', 'give' ),
503 + 'show' => true,
504 + ]
505 + );
430 506 break;
431 507
432 - case 'profile-updated' :
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 - ) );
508 + case 'disconnect-user':
509 + Give()->notices->register_notice(
510 + [
511 + 'id' => 'give-disconnect-user',
512 + 'type' => 'updated',
513 + 'description' => __( 'User has been successfully disconnected from donor.', 'give' ),
514 + 'show' => true,
515 + ]
516 + );
439 517 break;
518 +
519 + case 'profile-updated':
520 + Give()->notices->register_notice(
521 + [
522 + 'id' => 'give-profile-updated',
523 + 'type' => 'updated',
524 + 'description' => __( 'Donor information updated successfully.', 'give' ),
525 + 'show' => true,
526 + ]
527 + );
528 + break;
440 529 }// End switch().
441 530 }// End if().
442 531 }
443 532 }
533 +
534 + /**
535 + * Spam log admin notice
536 + */
537 + if (
538 + current_user_can( 'manage_give_settings' ) &&
539 + give_is_setting_enabled( give_get_option( 'akismet_spam_protection' ) )
540 + ) {
541 + global $wpdb;
542 +
543 + $current_time = current_time( 'timestamp' );
544 + $end_of_current_time_in_gmt = get_gmt_from_date( date( 'Y-m-d H:i:s', strtotime( 'tomorrow', $current_time ) ), 'U' );
545 + $current_time_gmt = get_gmt_from_date( date( 'Y-m-d H:i:s', $current_time ), 'U' );
546 +
547 + $spam_count = DB::get_var(
548 + DB::prepare( "SELECT COUNT(id) FROM {$wpdb->give_log} WHERE log_type = %s AND date >= CURDATE();", LogType::SPAM )
549 + );
550 +
551 + if ( $spam_count && ! Give_Admin_Settings::is_setting_page( 'logs', 'spam' ) ) {
552 + Give()->notices->register_notice(
553 + [
554 + 'id' => 'give-new-akismet-spam-found',
555 + 'type' => 'warning',
556 + 'description' => sprintf(
557 + __( 'Akismet flagged %1$s %2$s as spam. If you believe %7$s %5$s actual %6$s, you can whitelist %7$s to allow the %6$s to process donations. <a href="%3$s" title="%4$s">Click here</a> to review spam logs.', 'give' ),
558 + $spam_count,
559 + _n( 'donor email', 'donor emails', $spam_count, 'give' ),
560 + esc_url( admin_url( 'edit.php?post_type=give_forms&page=give-tools&tab=logs&section=spam' ) ),
561 + __( 'Go to spam log list page', 'give' ),
562 + _n( 'was', 'were', $spam_count, 'give' ),
563 + _n( 'donor', 'donors', $spam_count, 'give' ),
564 + _n( 'this', 'these', $spam_count, 'give' )
565 + ),
566 + 'dismissible_type' => 'user',
567 + 'dismiss_interval' => 'custom',
568 + 'dismiss_interval_time' => $end_of_current_time_in_gmt - $current_time_gmt,
569 + ]
570 + );
571 + }
572 + }
444 573 }
445 574
446 575 add_action( 'admin_notices', '_give_register_admin_notices', - 1 );
447 576
@@ -465,17 +594,19 @@
465 594 return false;
466 595 }
467 596
468 597 // 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 - ) );
598 + $wp_admin_bar->add_menu(
599 + [
600 + 'id' => 'give-test-notice',
601 + 'href' => admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=gateways' ),
602 + 'parent' => 'top-secondary',
603 + 'title' => __( 'GiveWP Test Mode Active', 'give' ),
604 + 'meta' => [
605 + 'class' => 'give-test-mode-active',
606 + ],
607 + ]
608 + );
478 609
479 610 return true;
480 611 }
481 612
@@ -514,8 +645,24 @@
514 645 function give_import_page_link_callback() {
515 646 ?>
516 647 <a href="<?php echo esc_url( give_import_page_url() ); ?>"
517 648 class="page-import-action page-title-action"><?php _e( 'Import Donations', 'give' ); ?></a>
649 + <script>
650 + function showReactTable () {
651 + fetch( '<?php echo esc_url_raw(rest_url('give-api/v2/admin/donations/view?isLegacy=0')) ?>', {
652 + method: 'GET',
653 + headers: {
654 + ['X-WP-Nonce']: '<?php echo wp_create_nonce('wp_rest') ?>'
655 + }
656 + })
657 + .then((res) => {
658 + window.location.reload();
659 + });
660 + }
661 + </script>
662 + <button onclick="showReactTable()" class="page-title-action">
663 + <?php _e('Switch to New View', 'give') ?>
664 + </button>
518 665
519 666 <?php
520 667 // Check if view donation single page only.
521 668 if ( ! empty( $_REQUEST['view'] ) && 'view-payment-details' === (string) give_clean( $_REQUEST['view'] ) && 'give-payment-history' === give_clean( $_REQUEST['page'] ) ) {
@@ -531,14 +678,35 @@
531 678
532 679 add_action( 'give_payments_page_top', 'give_import_page_link_callback', 11 );
533 680
534 681 /**
682 + * Avoid insecure usage of `unserialize` when the data could be submitted by the user.
683 + *
684 + * @since 3.16.1 Use Utils::giveMaybeSafeUnserialize() method
685 + * @since 3.5.0
686 + *
687 + * @param string $data Data that might be unserialized.
688 + *
689 + * @return mixed Unserialized data can be any type.
690 + */
691 +function give_maybe_safe_unserialize($data)
692 +{
693 + return Utils::maybeSafeUnserialize($data);
694 +}
695 +
696 +/**
535 697 * Load donation import ajax callback
536 698 * Fire when importing from CSV start
537 699 *
700 + * @since 4.11.0 Updated error handling to display errors in the import page.
701 + * @since 3.5.0 Extract safe unserialize logic to a function and use it in other places.
702 + * @since 2.25.3 Append nonce to response url.
538 703 * @since 1.8.13
539 704 */
540 705 function give_donation_import_callback() {
706 +
707 + check_ajax_referer('give_donation_import');
708 +
541 709 // Bailout.
542 710 if ( ! current_user_can( 'manage_give_settings' ) ) {
543 711 give_die();
544 712 }
@@ -545,9 +713,9 @@
545 713
546 714 // Disable Give cache
547 715 Give_Cache::get_instance()->disable();
548 716
549 - $import_setting = array();
717 + $import_setting = [];
550 718 $fields = isset( $_POST['fields'] ) ? $_POST['fields'] : null;
551 719
552 720 parse_str( $fields, $output );
553 721
@@ -558,9 +726,9 @@
558 726 $import_setting['delete_csv'] = $output['delete_csv'];
559 727 $import_setting['dry_run'] = $output['dry_run'];
560 728
561 729 // Parent key id.
562 - $main_key = maybe_unserialize( $output['main_key'] );
730 + $main_key = give_maybe_safe_unserialize($output['main_key']);
563 731
564 732 $current = absint( $_REQUEST['current'] );
565 733 $total_ajax = absint( $_REQUEST['total_ajax'] );
566 734 $start = absint( $_REQUEST['start'] );
@@ -574,19 +742,21 @@
574 742 $delimiter = $output['delimiter'];
575 743 }
576 744
577 745 // Processing done here.
578 - $raw_data = give_get_donation_data_from_csv( $output['csv'], $start, $end, $delimiter );
579 - $raw_key = maybe_unserialize( $output['mapto'] );
746 + $raw_data = give_get_donation_data_from_csv( $output['csv'], $start, $end, $delimiter);
747 + $raw_key = give_maybe_safe_unserialize($output['mapto']);
580 748 $import_setting['raw_key'] = $raw_key;
581 749
582 750 if ( ! empty( $output['dry_run'] ) ) {
583 751 $import_setting['csv_raw_data'] = give_get_donation_data_from_csv( $output['csv'], 1, $end, $delimiter );
584 752
585 - $import_setting['donors_list'] = Give()->donors->get_donors( array(
586 - 'number' => - 1,
587 - 'fields' => array( 'id', 'user_id', 'email' ),
588 - ) );
753 + $import_setting['donors_list'] = Give()->donors->get_donors(
754 + [
755 + 'number' => - 1,
756 + 'fields' => [ 'id', 'user_id', 'email' ],
757 + ]
758 + );
589 759 }
590 760
591 761 // Prevent normal emails.
592 762 remove_action( 'give_complete_donation', 'give_trigger_donation_receipt', 999 );
@@ -592,14 +762,20 @@
592 762 remove_action( 'give_complete_donation', 'give_trigger_donation_receipt', 999 );
593 763 remove_action( 'give_insert_user', 'give_new_user_notification', 10 );
594 764 remove_action( 'give_insert_payment', 'give_payment_save_page_data' );
595 765
596 - $current_key = $start;
597 - foreach ( $raw_data as $row_data ) {
598 - $import_setting['donation_key'] = $current_key;
599 - give_save_import_donation_to_db( $raw_key, $row_data, $main_key, $import_setting );
600 - $current_key ++;
601 - }
766 + $current_key = $start;
767 + foreach ( $raw_data as $row_data ) {
768 + $import_setting['donation_key'] = $current_key;
769 + $result = give_save_import_donation_to_db( $raw_key, $row_data, $main_key, $import_setting );
770 + if ( is_string( $result ) && ! empty( $result ) ) {
771 + if ( empty( $json_data['errors'] ) ) {
772 + $json_data['errors'] = [];
773 + }
774 + $json_data['errors'][] = sprintf( __( 'Row %1$d: %2$s', 'give' ), $current_key, $result );
775 + }
776 + $current_key ++;
777 + }
602 778
603 779 // Check if function exists or not.
604 780 if ( function_exists( 'give_payment_save_page_data' ) ) {
605 781 add_action( 'give_insert_payment', 'give_payment_save_page_data' );
@@ -607,12 +783,12 @@
607 783 add_action( 'give_insert_user', 'give_new_user_notification', 10, 2 );
608 784 add_action( 'give_complete_donation', 'give_trigger_donation_receipt', 999 );
609 785
610 786 if ( $next == false ) {
611 - $json_data = array(
787 + $json_data = [
612 788 'success' => true,
613 789 'message' => __( 'All donation uploaded successfully!', 'give' ),
614 - );
790 + ];
615 791 } else {
616 792 $index_start = $start;
617 793 $index_end = $end;
618 794 $last = false;
@@ -624,9 +800,9 @@
624 800 if ( $index_end >= $total ) {
625 801 $index_end = $total;
626 802 $last = true;
627 803 }
628 - $json_data = array(
804 + $json_data = [
629 805 'raw_data' => $raw_data,
630 806 'raw_key' => $raw_key,
631 807 'next' => $next,
632 808 'start' => $index_start,
@@ -631,20 +807,23 @@
631 807 'next' => $next,
632 808 'start' => $index_start,
633 809 'end' => $index_end,
634 810 'last' => $last,
635 - );
811 + ];
636 812 }
637 813
638 - $url = give_import_page_url( array(
639 - 'step' => '4',
640 - 'importer-type' => 'import_donations',
641 - 'csv' => $output['csv'],
642 - 'total' => $total,
643 - 'delete_csv' => $import_setting['delete_csv'],
644 - 'success' => ( isset( $json_data['success'] ) ? $json_data['success'] : '' ),
645 - 'dry_run' => $output['dry_run'],
646 - ) );
814 + $url = give_import_page_url(
815 + [
816 + 'step' => '4',
817 + 'importer-type' => 'import_donations',
818 + 'csv' => $output['csv'],
819 + 'total' => $total,
820 + 'delete_csv' => $import_setting['delete_csv'],
821 + 'success' => ( isset( $json_data['success'] ) ? $json_data['success'] : '' ),
822 + 'dry_run' => $output['dry_run'],
823 + '_wpnonce' => wp_create_nonce( 'give_donation_import_success' ),
824 + ]
825 + );
647 826 $json_data['url'] = $url;
648 827
649 828 $current ++;
650 829 $json_data['current'] = $current;
@@ -661,8 +840,129 @@
661 840
662 841 add_action( 'wp_ajax_give_donation_import', 'give_donation_import_callback' );
663 842
664 843 /**
844 + * Load subscription import ajax callback
845 + *
846 + * @since 4.11.0
847 + */
848 +function give_subscription_import_callback() {
849 +
850 + check_ajax_referer('give_subscription_import');
851 +
852 + if ( ! current_user_can( 'manage_give_settings' ) ) {
853 + give_die();
854 + }
855 +
856 + // Disable Give cache
857 + Give_Cache::get_instance()->disable();
858 +
859 + $import_setting = [];
860 + $fields = isset( $_POST['fields'] ) ? $_POST['fields'] : null;
861 +
862 + parse_str( $fields, $output );
863 +
864 + $import_setting['mode'] = $output['mode'];
865 + $import_setting['create_user'] = isset($output['create_user']) ? $output['create_user'] : '0';
866 + $import_setting['delimiter'] = $output['delimiter'];
867 + $import_setting['csv'] = $output['csv'];
868 + $import_setting['delete_csv'] = $output['delete_csv'];
869 + $import_setting['dry_run'] = $output['dry_run'];
870 +
871 + $main_key = give_maybe_safe_unserialize($output['main_key']);
872 +
873 + $current = absint( $_REQUEST['current'] );
874 + $total_ajax = absint( $_REQUEST['total_ajax'] );
875 + $start = absint( $_REQUEST['start'] );
876 + $end = absint( $_REQUEST['end'] );
877 + $next = absint( $_REQUEST['next'] );
878 + $total = absint( $_REQUEST['total'] );
879 + $per_page = absint( $_REQUEST['per_page'] );
880 + $delimiter = empty( $output['delimiter'] ) ? ',' : $output['delimiter'];
881 +
882 + // Ensure importer class is loaded for admin-ajax context
883 + if ( ! class_exists( 'Give_Import_Subscriptions' ) ) {
884 + require_once GIVE_PLUGIN_DIR . 'includes/admin/tools/import/class-give-import-subscriptions.php';
885 + }
886 +
887 + $importer = \Give_Import_Subscriptions::get_instance();
888 +
889 + // Processing
890 + $raw_data = $importer->get_subscription_data_from_csv( $output['csv'], $start, $end, $delimiter );
891 + $raw_key = give_maybe_safe_unserialize($output['mapto']);
892 + $import_setting['raw_key'] = $raw_key;
893 +
894 + $current_key = $start;
895 + foreach ( $raw_data as $row_data ) {
896 + $import_setting['row_key'] = $current_key;
897 + $result = $importer->import_row( $raw_key, $row_data, $main_key, $import_setting );
898 + if ( is_string( $result ) && ! empty( $result ) ) {
899 + if ( empty( $json_data['errors'] ) ) {
900 + $json_data['errors'] = [];
901 + }
902 + $json_data['errors'][] = sprintf( __( 'Row %1$d: %2$s', 'give' ), $current_key, $result );
903 + }
904 + $current_key ++;
905 + }
906 +
907 + if ( $next == false ) {
908 + $json_data = [
909 + 'success' => true,
910 + 'message' => __( 'All subscriptions uploaded successfully!', 'give' ),
911 + ];
912 + } else {
913 + $index_start = $start;
914 + $index_end = $end;
915 + $last = false;
916 + $next = true;
917 + if ( $next ) {
918 + $index_start = $index_start + $per_page;
919 + $index_end = $per_page + ( $index_start - 1 );
920 + }
921 + if ( $index_end >= $total ) {
922 + $index_end = $total;
923 + $last = true;
924 + }
925 + $json_data = [
926 + 'raw_data' => $raw_data,
927 + 'raw_key' => $raw_key,
928 + 'next' => $next,
929 + 'start' => $index_start,
930 + 'end' => $index_end,
931 + 'last' => $last,
932 + ];
933 + }
934 +
935 + $url = give_import_page_url(
936 + [
937 + 'step' => '4',
938 + 'importer-type' => 'import_subscriptions',
939 + 'csv' => $output['csv'],
940 + 'total' => $total,
941 + 'delete_csv' => $import_setting['delete_csv'],
942 + 'success' => ( isset( $json_data['success'] ) ? $json_data['success'] : '' ),
943 + 'dry_run' => $output['dry_run'],
944 + '_wpnonce' => wp_create_nonce( 'give_subscription_import_success' ),
945 + ]
946 + );
947 + $json_data['url'] = $url;
948 +
949 + $current ++;
950 + $json_data['current'] = $current;
951 +
952 + $percentage = ( 100 / ( $total_ajax + 1 ) ) * $current;
953 + $json_data['percentage'] = $percentage;
954 +
955 + // Enable Give cache
956 + Give_Cache::get_instance()->enable();
957 +
958 + $json_data = apply_filters( 'give_import_ajax_responces', $json_data, $fields );
959 + wp_die( json_encode( $json_data ) );
960 +}
961 +
962 +add_action( 'wp_ajax_give_subscription_import', 'give_subscription_import_callback' );
963 +
964 +/**
665 965 * Load core settings import ajax callback
666 966 * Fire when importing from JSON start
667 967 *
668 968 * @since 1.8.17
@@ -668,8 +968,10 @@
668 968 * @since 1.8.17
669 969 */
670 970
671 971 function give_core_settings_import_callback() {
972 + check_ajax_referer( 'give_core_settings_import' );
973 +
672 974 // Bailout.
673 975 if ( ! current_user_can( 'manage_give_settings' ) ) {
674 976 give_die();
675 977 }
@@ -700,10 +1002,10 @@
700 1002 // Get the json data from the file and then alter it in array format
701 1003 $json_string = give_get_core_settings_json( $file_name );
702 1004 $json_to_array = json_decode( $json_string, true );
703 1005
704 - // get the current settign from the options table.
705 - $host_give_options = get_option( 'give_settings', array() );
1006 + // get the current setting from the options table.
1007 + $host_give_options = Give_Cache_Setting::get_settings();
706 1008
707 1009 // Save old settins for backup.
708 1010 update_option( 'give_settings_old', $host_give_options, false );
709 1011
@@ -713,13 +1015,14 @@
713 1015 * @access public
714 1016 *
715 1017 * @since 1.8.17
716 1018 *
717 - * @param array $json_to_array Setting that are being going to get imported
718 - * @param array $type Type of Import
1019 + * @param array $type Type of Import
719 1020 * @param array $host_give_options Setting old setting that used to be in the options table.
720 - * @param array $fields Data that is being send from the ajax
1021 + * @param array $fields Data that is being send from the ajax
721 1022 *
1023 + * @param array $json_to_array Setting that are being going to get imported
1024 + *
722 1025 * @return array $json_to_array Setting that are being going to get imported
723 1026 */
724 1027 $json_to_array = (array) apply_filters( 'give_import_core_settings_data', $json_to_array, $type, $host_give_options, $fields );
725 1028
@@ -735,16 +1038,20 @@
735 1038 *
736 1039 * @access public
737 1040 *
738 1041 * @since 1.8.17
739 - *
740 1042 * @return array $url
741 1043 */
742 - $json_data['url'] = give_import_page_url( (array) apply_filters( 'give_import_core_settings_success_url', array(
743 - 'step' => ( empty( $json_data['success'] ) ? '1' : '3' ),
744 - 'importer-type' => 'import_core_setting',
745 - 'success' => ( empty( $json_data['success'] ) ? '0' : '1' ),
746 - ) ) );
1044 + $json_data['url'] = give_import_page_url(
1045 + (array) apply_filters(
1046 + 'give_import_core_settings_success_url',
1047 + [
1048 + 'step' => ( empty( $json_data['success'] ) ? '1' : '3' ),
1049 + 'importer-type' => 'import_core_setting',
1050 + 'success' => ( empty( $json_data['success'] ) ? '0' : '1' ),
1051 + ]
1052 + )
1053 + );
747 1054
748 1055 wp_send_json( $json_data );
749 1056 }
750 1057
@@ -764,13 +1071,14 @@
764 1071
765 1072 /**
766 1073 * Validate Fields of User Profile
767 1074 *
768 - * @param object $errors Object of WP Errors.
1075 + * @since 2.0
1076 + *
769 1077 * @param int|bool $update True or False.
770 - * @param object $user WP User Data.
1078 + * @param object $user WP User Data.
771 1079 *
772 - * @since 2.0
1080 + * @param object $errors Object of WP Errors.
773 1081 *
774 1082 * @return mixed
775 1083 */
776 1084 function give_validate_user_profile( $errors, $update, $user ) {
@@ -803,32 +1111,29 @@
803 1111
804 1112 /**
805 1113 * Show Donor Information on User Profile Page.
806 1114 *
1115 + * @since 2.0
1116 + *
807 1117 * @param object $user User Object.
808 1118 *
809 - * @since 2.0
810 1119 */
811 1120 function give_donor_information_profile_fields( $user ) {
812 1121 $donor = Give()->donors->get_donor_by( 'user_id', $user->ID );
813 1122
814 1123 // Display Donor Information, only if donor is attached with User.
815 - if ( ! empty( $donor->user_id ) ) {
1124 + if ( ! empty( $donor->user_id ) ) :
816 1125 ?>
817 - <table class="form-table">
818 - <tbody>
819 - <tr>
820 - <th scope="row"><?php _e( 'Donor', 'give' ); ?></th>
821 - <td>
822 - <a href="<?php echo admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ); ?>">
823 - <?php _e( 'View Donor Information', 'give' ); ?>
824 - </a>
825 - </td>
826 - </tr>
827 - </tbody>
828 - </table>
1126 + <tr>
1127 + <th scope="row"><?php _e( 'Donor', 'give' ); ?></th>
1128 + <td>
1129 + <a href="<?php echo admin_url( 'edit.php?post_type=give_forms&page=give-donors&view=overview&id=' . $donor->id ); ?>">
1130 + <?php _e( 'View Donor Information', 'give' ); ?>
1131 + </a>
1132 + </td>
1133 + </tr>
829 1134 <?php
830 - }
1135 + endif;
831 1136 }
832 1137
833 1138 add_action( 'personal_options', 'give_donor_information_profile_fields' );
834 1139 /**
@@ -834,13 +1139,12 @@
834 1139 /**
835 1140 * Get Array of WP User Roles.
836 1141 *
837 1142 * @since 1.8.13
838 - *
839 1143 * @return array
840 1144 */
841 1145 function give_get_user_roles() {
842 - $user_roles = array();
1146 + $user_roles = [];
843 1147
844 1148 // Loop through User Roles.
845 1149 foreach ( get_editable_roles() as $role_name => $role_info ) :
846 1150 $user_roles[ $role_name ] = $role_info['name'];
@@ -850,49 +1154,110 @@
850 1154 }
851 1155
852 1156
853 1157 /**
1158 + * Get user roles that are safe for donor registration.
1159 + *
1160 + * This excludes privileged roles like administrator, editor, give_accountant, etc.
1161 + * to prevent security issues if the default donor role setting is misconfigured.
1162 + * Only basic subscriber-level roles should be available for donor registration.
1163 + *
1164 + * @since 4.14.0
1165 + * @return array
1166 + */
1167 +function give_get_donor_safe_user_roles() {
1168 + $user_roles = [];
1169 +
1170 + // Capabilities that indicate a privileged role - exclude these
1171 + $privileged_caps = [
1172 + // WordPress privileged caps
1173 + 'manage_options',
1174 + 'edit_users',
1175 + 'delete_users',
1176 + 'create_users',
1177 + 'edit_others_posts',
1178 + 'delete_others_posts',
1179 + 'edit_pages',
1180 + 'edit_others_pages',
1181 + 'publish_pages',
1182 + 'delete_pages',
1183 + 'edit_posts',
1184 + // GiveWP privileged caps - access to sensitive donor/payment data
1185 + 'view_give_reports',
1186 + 'export_give_reports',
1187 + 'manage_give_settings',
1188 + 'view_give_sensitive_data',
1189 + 'edit_give_payments',
1190 + 'edit_give_forms',
1191 + ];
1192 +
1193 + foreach ( get_editable_roles() as $role_name => $role_info ) {
1194 + $is_privileged = false;
1195 +
1196 + // Check if role has any privileged capabilities
1197 + foreach ( $privileged_caps as $cap ) {
1198 + if ( ! empty( $role_info['capabilities'][ $cap ] ) ) {
1199 + $is_privileged = true;
1200 + break;
1201 + }
1202 + }
1203 +
1204 + // Only include non-privileged roles
1205 + if ( ! $is_privileged ) {
1206 + $user_roles[ $role_name ] = $role_info['name'];
1207 + }
1208 + }
1209 +
1210 + return $user_roles;
1211 +}
1212 +
1213 +/**
854 1214 * Ajax handle for donor address.
855 1215 *
856 1216 * @since 2.0
857 - *
858 - * @return string
1217 + * @since 2.11.0 decode url before parsing and sanitizing url when set $post.
1218 + * @since 4.9.0 rename function - PHP 8 compatibility
1219 + * @return void
859 1220 */
860 -function __give_ajax_donor_manage_addresses() {
1221 +function give_ajax_donor_manage_addresses() {
861 1222 // Bailout.
862 1223 if (
863 1224 empty( $_POST['form'] ) ||
864 1225 empty( $_POST['donorID'] )
865 1226 ) {
866 - wp_send_json_error( array(
867 - 'error' => 1,
868 - ) );
1227 + wp_send_json_error(
1228 + [
1229 + 'error' => 1,
1230 + ]
1231 + );
869 1232 }
870 1233
871 - $post = give_clean( wp_parse_args( $_POST ) );
1234 + $post = give_clean( wp_parse_args( urldecode_deep( $_POST ) ) );
872 1235 $donorID = absint( $post['donorID'] );
873 1236 $form_data = give_clean( wp_parse_args( $post['form'] ) );
874 1237 $is_multi_address_type = ( 'billing' === $form_data['address-id'] || false !== strpos( $form_data['address-id'], '_' ) );
1238 + $exploded_address_id = explode( '_', $form_data['address-id'] );
875 1239 $address_type = false !== strpos( $form_data['address-id'], '_' ) ?
876 - array_shift( explode( '_', $form_data['address-id'] ) ) :
1240 + array_shift( $exploded_address_id ) :
877 1241 $form_data['address-id'];
878 1242 $address_id = false !== strpos( $form_data['address-id'], '_' ) ?
879 - array_pop( explode( '_', $form_data['address-id'] ) ) :
1243 + array_pop( $exploded_address_id ) :
880 1244 null;
881 - $response_data = array(
1245 + $response_data = [
882 1246 'action' => $form_data['address-action'],
883 1247 'id' => $form_data['address-id'],
884 - );
1248 + ];
885 1249
886 1250 // Security check.
887 1251 if ( ! wp_verify_nonce( $form_data['_wpnonce'], 'give-manage-donor-addresses' ) ) {
888 - wp_send_json_error( array(
1252 + wp_send_json_error(
1253 + [
889 1254 'error' => 1,
890 1255 'error_msg' => wp_sprintf(
891 1256 '<div class="notice notice-error"><p>%s</p></div>',
892 1257 __( 'Error: Security issue.', 'give' )
893 1258 ),
894 - )
1259 + ]
895 1260 );
896 1261 }
897 1262
898 1263 $donor = new Give_Donor( $donorID );
@@ -898,11 +1263,13 @@
898 1263 $donor = new Give_Donor( $donorID );
899 1264
900 1265 // Verify donor.
901 1266 if ( ! $donor->id ) {
902 - wp_send_json_error( array(
903 - 'error' => 3,
904 - ) );
1267 + wp_send_json_error(
1268 + [
1269 + 'error' => 3,
1270 + ]
1271 + );
905 1272 }
906 1273
907 1274 // Unset all data except address.
908 1275 unset(
@@ -915,15 +1282,16 @@
915 1282 switch ( $response_data['action'] ) {
916 1283
917 1284 case 'add':
918 1285 if ( ! $donor->add_address( "{$address_type}[]", $form_data ) ) {
919 - wp_send_json_error( array(
1286 + wp_send_json_error(
1287 + [
920 1288 'error' => 1,
921 1289 'error_msg' => wp_sprintf(
922 1290 '<div class="notice notice-error"><p>%s</p></div>',
923 1291 __( 'Error: Unable to save the address. Please check if address already exist.', 'give' )
924 1292 ),
925 - )
1293 + ]
926 1294 );
927 1295 }
928 1296
929 1297 $total_addresses = count( $donor->address[ $address_type ] );
@@ -937,16 +1305,16 @@
937 1305 $address_id = $is_multi_address_type ?
938 1306 end( $array_keys ) :
939 1307 $address_type;
940 1308
941 - $response_data['address_html'] = __give_get_format_address(
1309 + $response_data['address_html'] = give_get_format_address(
942 1310 end( $donor->address['billing'] ),
943 - array(
1311 + [
944 1312 // We can add only billing address from donor screen.
945 1313 'type' => 'billing',
946 1314 'id' => $address_id,
947 1315 'index' => ++ $address_index,
948 - )
1316 + ]
949 1317 );
950 1318 $response_data['success_msg'] = wp_sprintf(
951 1319 '<div class="notice updated"><p>%s</p></div>',
952 1320 __( 'Successfully added a new address to the donor.', 'give' )
@@ -959,15 +1327,16 @@
959 1327 break;
960 1328
961 1329 case 'remove':
962 1330 if ( ! $donor->remove_address( $response_data['id'] ) ) {
963 - wp_send_json_error( array(
1331 + wp_send_json_error(
1332 + [
964 1333 'error' => 2,
965 1334 'error_msg' => wp_sprintf(
966 1335 '<div class="notice notice-error"><p>%s</p></div>',
967 1336 __( 'Error: Unable to delete address.', 'give' )
968 1337 ),
969 - )
1338 + ]
970 1339 );
971 1340 }
972 1341
973 1342 $response_data['success_msg'] = wp_sprintf(
@@ -978,27 +1347,28 @@
978 1347 break;
979 1348
980 1349 case 'update':
981 1350 if ( ! $donor->update_address( $response_data['id'], $form_data ) ) {
982 - wp_send_json_error( array(
1351 + wp_send_json_error(
1352 + [
983 1353 'error' => 3,
984 1354 'error_msg' => wp_sprintf(
985 1355 '<div class="notice notice-error"><p>%s</p></div>',
986 1356 __( 'Error: Unable to update address. Please check if address already exist.', 'give' )
987 1357 ),
988 - )
1358 + ]
989 1359 );
990 1360 }
991 1361
992 - $response_data['address_html'] = __give_get_format_address(
1362 + $response_data['address_html'] = give_get_format_address(
993 1363 $is_multi_address_type ?
994 1364 $donor->address[ $address_type ][ $address_id ] :
995 1365 $donor->address[ $address_type ],
996 - array(
1366 + [
997 1367 'type' => $address_type,
998 1368 'id' => $address_id,
999 1369 'index' => $address_id,
1000 - )
1370 + ]
1001 1371 );
1002 1372 $response_data['success_msg'] = wp_sprintf(
1003 1373 '<div class="notice updated"><p>%s</p></div>',
1004 1374 __( 'Successfully updated a address of donor', 'give' )
@@ -1009,13 +1379,14 @@
1009 1379
1010 1380 wp_send_json_success( $response_data );
1011 1381 }
1012 1382
1013 -add_action( 'wp_ajax_donor_manage_addresses', '__give_ajax_donor_manage_addresses' );
1383 +add_action( 'wp_ajax_donor_manage_addresses', 'give_ajax_donor_manage_addresses');
1014 1384
1015 1385 /**
1016 1386 * Admin donor billing address label
1017 1387 *
1388 + * @since 4.9.0 rename function - PHP 8 compatibility
1018 1389 * @since 2.0
1019 1390 *
1020 1391 * @param string $address_label
1021 1392 *
@@ -1020,19 +1391,20 @@
1020 1391 * @param string $address_label
1021 1392 *
1022 1393 * @return string
1023 1394 */
1024 -function __give_donor_billing_address_label( $address_label ) {
1395 +function give_donor_billing_address_label( $address_label ) {
1025 1396 $address_label = __( 'Billing Address', 'give' );
1026 1397
1027 1398 return $address_label;
1028 1399 }
1029 1400
1030 -add_action( 'give_donor_billing_address_label', '__give_donor_billing_address_label' );
1401 +add_action( 'give_donor_billing_address_label', 'give_donor_billing_address_label');
1031 1402
1032 1403 /**
1033 1404 * Admin donor personal address label
1034 1405 *
1406 + * @since 4.9.0 rename function - PHP 8 compatibility
1035 1407 * @since 2.0
1036 1408 *
1037 1409 * @param string $address_label
1038 1410 *
@@ -1037,25 +1409,25 @@
1037 1409 * @param string $address_label
1038 1410 *
1039 1411 * @return string
1040 1412 */
1041 -function __give_donor_personal_address_label( $address_label ) {
1413 +function give_donor_personal_address_label( $address_label ) {
1042 1414 $address_label = __( 'Personal Address', 'give' );
1043 1415
1044 1416 return $address_label;
1045 1417 }
1046 1418
1047 -add_action( 'give_donor_personal_address_label', '__give_donor_personal_address_label' );
1419 +add_action( 'give_donor_personal_address_label', 'give_donor_personal_address_label');
1048 1420
1049 1421 /**
1050 1422 * Update Donor Information when User Profile is updated from admin.
1051 1423 * Note: for internal use only.
1052 1424 *
1425 + * @since 2.0
1426 + *
1053 1427 * @param int $user_id
1054 1428 *
1055 1429 * @access public
1056 - * @since 2.0
1057 - *
1058 1430 * @return bool
1059 1431 */
1060 1432 function give_update_donor_name_on_user_update( $user_id = 0 ) {
1061 1433
@@ -1073,11 +1445,14 @@
1073 1445 $last_name = ( $_POST['last_name'] ) ? give_clean( $_POST['last_name'] ) : get_user_meta( $user_id, 'last_name', true );
1074 1446 $full_name = strip_tags( wp_unslash( trim( "{$first_name} {$last_name}" ) ) );
1075 1447
1076 1448 // Assign User First name and Last name to Donor.
1077 - Give()->donors->update( $donor->id, array(
1078 - 'name' => $full_name,
1079 - ) );
1449 + Give()->donors->update(
1450 + $donor->id,
1451 + [
1452 + 'name' => $full_name,
1453 + ]
1454 + );
1080 1455 Give()->donor_meta->update_meta( $donor->id, '_give_donor_first_name', $first_name );
1081 1456 Give()->donor_meta->update_meta( $donor->id, '_give_donor_last_name', $last_name );
1082 1457
1083 1458 }
@@ -1093,11 +1468,12 @@
1093 1468 *
1094 1469 * @since 1.4.3
1095 1470 * @access public
1096 1471 *
1097 - * @param int $user_id User ID.
1098 - * @param WP_User|bool $old_user_data User data.
1472 + * @param WP_User|bool $old_user_data User data.
1099 1473 *
1474 + * @param int $user_id User ID.
1475 + *
1100 1476 * @return bool
1101 1477 */
1102 1478 function give_update_donor_email_on_user_update( $user_id = 0, $old_user_data = false ) {
1103 1479
@@ -1110,11 +1486,14 @@
1110 1486 $user = get_userdata( $user_id );
1111 1487
1112 1488 if ( ! empty( $user ) && $user->user_email !== $donor->email ) {
1113 1489
1114 - $success = Give()->donors->update( $donor->id, array(
1115 - 'email' => $user->user_email,
1116 - ) );
1490 + $success = Give()->donors->update(
1491 + $donor->id,
1492 + [
1493 + 'email' => $user->user_email,
1494 + ]
1495 + );
1117 1496
1118 1497 if ( $success ) {
1119 1498 // Update some payment meta if we need to
1120 1499 $payments_array = explode( ',', $donor->payment_ids );
@@ -1132,10 +1511,11 @@
1132 1511 * Fires after updating donor email on user update.
1133 1512 *
1134 1513 * @since 1.4.3
1135 1514 *
1136 - * @param WP_User $user WordPress User object.
1137 - * @param Give_Donor $donor Give donor object.
1515 + * @param Give_Donor $donor Give donor object.
1516 + *
1517 + * @param WP_User $user WordPress User object.
1138 1518 */
1139 1519 do_action( 'give_update_donor_email_on_user_update', $user, $donor );
1140 1520
1141 1521 }
@@ -1149,18 +1529,193 @@
1149 1529 /**
1150 1530 * Flushes Give's cache.
1151 1531 */
1152 1532 function give_cache_flush() {
1153 - $result = Give_Cache::flush_cache();
1533 + if (!is_user_logged_in() || !current_user_can('manage_give_settings')) {
1534 + wp_die();
1535 + }
1154 1536
1155 - if ( $result ) {
1156 - wp_send_json_success( array(
1157 - 'message' => __( 'Cache flushed successfully.', 'give' ),
1158 - ));
1159 - } else {
1160 - wp_send_json_error( array(
1161 - 'message' => __( 'An error occured while flushing the cache.', 'give' ),
1162 - ));
1537 + /**
1538 + * @since 2.25.2 add nonce check
1539 + */
1540 + check_ajax_referer('give_cache_flush');
1541 +
1542 + $result = Give_Cache::flush_cache();
1543 +
1544 + if ($result) {
1545 + wp_send_json_success(
1546 + [
1547 + 'message' => __('Cache flushed successfully.', 'give'),
1548 + ]
1549 + );
1550 + } else {
1551 + wp_send_json_error(
1552 + [
1553 + 'message' => __('An error occurred while flushing the cache.', 'give'),
1554 + ]
1555 + );
1556 + }
1557 +}
1558 +
1559 +add_action( 'wp_ajax_give_cache_flush', 'give_cache_flush', 10, 0 );
1560 +
1561 +
1562 +/**
1563 + * Log give addon activation time
1564 + *
1565 + * @since 2.5.0
1566 + *
1567 + * @param $network_wide
1568 + *
1569 + * @param $plugin
1570 + */
1571 +function give_log_addon_activation_time( $plugin, $network_wide ) {
1572 + if ( $network_wide ) {
1573 + return;
1163 1574 }
1575 +
1576 + $plugin_data = give_get_plugins( [ 'only_premium_add_ons' => true ] );
1577 + $plugin_data = ! empty( $plugin_data[ $plugin ] ) ? $plugin_data[ $plugin ] : [];
1578 +
1579 + if ( $plugin_data ) {
1580 + update_option( 'give_addon_last_activated', current_time( 'timestamp' ), 'no' );
1581 + }
1164 1582 }
1165 1583
1166 -add_action( 'wp_ajax_give_cache_flush', 'give_cache_flush', 10, 0 );
1584 +add_action( 'activate_plugin', 'give_log_addon_activation_time', 10, 2 );
1585 +
1586 +
1587 +/**
1588 + * Hide all admin notice from add-ons page
1589 + *
1590 + * Note: only for internal use
1591 + *
1592 + * @since 2.5.0
1593 + */
1594 +function give_hide_notices_on_add_ons_page() {
1595 + $page = ! empty( $_GET['page'] ) ? give_clean( $_GET['page'] ) : '';
1596 +
1597 + // Bailout.
1598 + if ( 'give-addons' !== $page ) {
1599 + return;
1600 + }
1601 +
1602 + remove_all_actions( 'admin_notices' );
1603 +}
1604 +
1605 +add_action( 'in_admin_header', 'give_hide_notices_on_add_ons_page', 999 );
1606 +
1607 +
1608 +/**
1609 + * Admin JS
1610 + *
1611 + * @since 2.5.0
1612 + */
1613 +function give_admin_quick_js() {
1614 + if ( is_multisite() && is_blog_admin() ) {
1615 + ?>
1616 + <script>
1617 + jQuery(document).ready(function ($) {
1618 + var $updateNotices = $('[id$="-update"] ', '.wp-list-table');
1619 +
1620 + if ($updateNotices.length) {
1621 + $.each($updateNotices, function (index, $updateNotice) {
1622 + $updateNotice = $($updateNotice);
1623 + $updateNotice.prev().addClass('update');
1624 + });
1625 + }
1626 + });
1627 + </script>
1628 + <?php
1629 + }
1630 +}
1631 +
1632 +add_action( 'admin_head', 'give_admin_quick_js' );
1633 +
1634 +/**
1635 + * Add Admin addon menu related scripts
1636 + *
1637 + * @since 2.6.0
1638 + */
1639 +function give_admin_addon_menu_inline_scripts() {
1640 + ?>
1641 + <script>
1642 + (function ($) {
1643 + const $addonLink = $('#menu-posts-give_forms a[href^="edit.php?post_type=give_forms&page=give-add-ons"]');
1644 + <?php if ( empty( give_get_plugins( [ 'only_premium_add_ons' => true ] ) ) ) : ?>
1645 + $addonLink.addClass('give-highlight');
1646 + $addonLink.prepend('<span class="dashicons dashicons-star-filled"></span>');
1647 + <?php endif; ?>
1648 + })(jQuery)
1649 + </script>
1650 + <style>
1651 + #menu-posts-give_forms a[href^="edit.php?post_type=give_forms&page=give-add-ons"].give-highlight {
1652 + color: rgb(43, 194, 83);
1653 + font-weight: 700;
1654 + vertical-align: top;
1655 + text-shadow: 0 1px 2px #00000080;
1656 + }
1657 +
1658 + #menu-posts-give_forms a[href^="edit.php?post_type=give_forms&page=give-add-ons"].give-highlight span.dashicons {
1659 + font-size: 14px !important;
1660 + width: auto;
1661 + height: 18px;
1662 + padding-right: 3px;
1663 + vertical-align: middle;
1664 + }
1665 + </style>
1666 + <?php
1667 +}
1668 +
1669 +add_action( 'admin_footer', 'give_admin_addon_menu_inline_scripts' );
1670 +
1671 +/**
1672 + * Handle akismet_deblacklist_spammed_email_handler give-action
1673 + *
1674 + * @since 2.5.14
1675 + *
1676 + * @param array $get
1677 + *
1678 + */
1679 +function give_akismet_deblacklist_spammed_email_handler( $get ) {
1680 + $email = ! empty( $get['email'] ) && is_email( $get['email'] ) ? give_clean( $get['email'] ) : '';
1681 + $log = ! empty( $get['log'] ) ? absint( $get['log'] ) : '';
1682 + $action = "give_akismet_deblacklist_spammed_email_{$email}";
1683 +
1684 + check_admin_referer( $action );
1685 + $emails = give_akismet_get_whitelisted_emails();
1686 +
1687 + if ( ! in_array( $email, $emails, true ) ) {
1688 + array_unshift( $emails, $email );
1689 +
1690 + give_update_option( 'akismet_whitelisted_email_addresses', $emails );
1691 +
1692 + // Redirect to Akismet setting page.
1693 + wp_safe_redirect( 'wp-admin/edit.php?post_type=give_forms&page=give-settings&tab=advanced&section=akismet-spam-protection&give-message=akismet-deblacklisted-email' );
1694 + }
1695 +}
1696 +
1697 +add_action( 'give_akismet_deblacklist_spammed_email', 'give_akismet_deblacklist_spammed_email_handler' );
1698 +
1699 +/**
1700 + * Add Custom setting view for form them setting panel
1701 + *
1702 + * @since 2.7.0
1703 + */
1704 +function give_render_form_theme_setting_panel() {
1705 + require_once GIVE_PLUGIN_DIR . 'src/Views/Admin/Form/Metabox-Settings.php';
1706 +}
1707 +
1708 +add_action( 'give_post_form_template_options_settings', 'give_render_form_theme_setting_panel' );
1709 +
1710 +/**
1711 + * Add Custom setting view for form grid setting panel
1712 + *
1713 + * @since 2.20.0
1714 + */
1715 +function give_render_form_grid_setting_panel()
1716 +{
1717 + require_once GIVE_PLUGIN_DIR . 'src/Views/Admin/Form/FormGrid-Settings.php';
1718 +}
1719 +
1720 +add_action('give_post_form_grid_options_settings', 'give_render_form_grid_setting_panel');
1721 +