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