PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.1.0
GiveWP – Donation Plugin and Fundraising Platform v4.1.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\Helpers\Utils;
5 use Give\Log\ValueObjects\LogType;
6
7 /**
8 * Admin Actions
9 *
10 * @package Give
11 * @since 1.0
12 * @copyright Copyright (c) 2016, GiveWP
13 * @license https://opensource.org/licenses/gpl-license GNU Public License
14 * @subpackage Admin/Actions
15 */
16
17 // Exit if accessed directly.
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 /**
23 * Load wp editor by ajax.
24 *
25 * @since 1.8
26 */
27 function give_load_wp_editor() {
28 if ( ! isset( $_POST['wp_editor'] ) || ! current_user_can( 'edit_give_forms' ) ) {
29 die();
30 }
31
32 $wp_editor = json_decode( base64_decode( $_POST['wp_editor'] ), true );
33 $wp_editor[2]['textarea_name'] = give_clean( $_POST['textarea_name'] );
34
35 wp_editor( wp_kses_post( $wp_editor[0] ), give_clean( $_POST['wp_editor_id'] ), $wp_editor[2] );
36
37 die();
38 }
39
40 add_action( 'wp_ajax_give_load_wp_editor', 'give_load_wp_editor' );
41
42
43 /**
44 * Redirect admin to clean url give admin pages.
45 *
46 * @since 2.25.2 Removed _wpnonce from list of removed args.
47 * @since 1.8
48 *
49 * @return bool
50 */
51 function give_redirect_to_clean_url_admin_pages() {
52 // Give admin pages.
53 $give_pages = [
54 'give-payment-history',
55 'give-donors',
56 'give-reports',
57 'give-tools',
58 ];
59
60 // Get current page.
61 $current_page = isset( $_GET['page'] ) ? esc_attr( $_GET['page'] ) : '';
62
63 // Bailout.
64 if (
65 empty( $current_page )
66 || empty( $_GET['_wp_http_referer'] )
67 || ! in_array( $current_page, $give_pages )
68 ) {
69 return false;
70 }
71
72 /**
73 * Verify current page request.
74 *
75 * @since 1.8
76 */
77 $redirect = apply_filters( "give_validate_{$current_page}", true );
78
79 if ( $redirect ) {
80 // Redirect.
81 wp_redirect(
82 esc_url_raw(
83 remove_query_arg(
84 ['_wp_http_referer'],
85 wp_unslash($_SERVER['REQUEST_URI'])
86 )
87 )
88 );
89 exit;
90 }
91 }
92
93 add_action( 'admin_init', 'give_redirect_to_clean_url_admin_pages' );
94
95
96 /**
97 * Hide Outdated PHP Notice Shortly.
98 *
99 * This code is used with AJAX call to hide outdated PHP notice for a short period of time
100 *
101 * @since 1.8.9
102 * @return void
103 */
104 function give_hide_outdated_php_notice() {
105
106 if ( ! isset( $_POST['_give_hide_outdated_php_notices_shortly'] ) || ! current_user_can( 'manage_give_settings' ) ) {
107 give_die();
108 }
109
110 // Transient key name.
111 $transient_key = '_give_hide_outdated_php_notices_shortly';
112
113 if ( Give_Cache::get( $transient_key, true ) ) {
114 return;
115 }
116
117 // Hide notice for 24 hours.
118 Give_Cache::set( $transient_key, true, DAY_IN_SECONDS, true );
119
120 give_die();
121
122 }
123
124 add_action( 'wp_ajax_give_hide_outdated_php_notice', 'give_hide_outdated_php_notice' );
125
126 /**
127 * Register admin notices.
128 *
129 * @since 2.25.2 Add nonce check for bulk action.
130 * @since 1.8.9
131 */
132 function _give_register_admin_notices() {
133 // Bailout.
134 if ( ! is_admin() ) {
135 return;
136 }
137
138 // Bulk action notices.
139 if (
140 isset( $_GET['action'] ) &&
141 ! empty( $_GET['action'] )
142 ) {
143
144 // Add payment bulk notice.
145 if (
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'] )
151 ) {
152 $payment_count = isset( $_GET['payment'] ) ? count( $_GET['payment'] ) : 0;
153
154 switch ( $_GET['action'] ) {
155 case 'delete':
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
168 ),
169 'show' => true,
170 ]
171 );
172
173 break;
174
175 case 'resend-receipt':
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.',
210 $payment_count,
211 'give'
212 ),
213 'show' => true,
214 ]
215 );
216 break;
217 }// End switch().
218 }// End if().
219 }// End if().
220
221 // Add give message notices.
222 $message_notices = give_get_admin_messages_key();
223 if ( ! empty( $message_notices ) ) {
224 foreach ( $message_notices as $message_notice ) {
225 // Donation reports errors.
226 if ( current_user_can( 'view_give_reports' ) ) {
227 switch ( $message_notice ) {
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 );
237 break;
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 );
247 break;
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 );
257 break;
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 );
267 break;
268 }// End switch().
269 }// End if().
270
271 // Give settings notices and errors.
272 if ( current_user_can( 'manage_give_settings' ) ) {
273 switch ( $message_notice ) {
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 );
283 break;
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 );
293 break;
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 );
303 break;
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 );
313 break;
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 );
323 break;
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 );
333 break;
334 case 'matched-success-failure-page':
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 );
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;
355 }// End switch().
356 }// End if().
357
358 // Payments errors.
359 if ( current_user_can( 'edit_give_payments' ) ) {
360 switch ( $message_notice ) {
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 );
370 break;
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 );
380 break;
381 }// End switch().
382 }// End if().
383
384 // Donor Notices.
385 if ( current_user_can( 'edit_give_payments' ) ) {
386 switch ( $message_notice ) {
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 );
396 break;
397
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 );
407 break;
408
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 );
418 break;
419
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 );
429 break;
430
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 );
440 break;
441
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 );
451 break;
452
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 );
462 break;
463
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 );
473 break;
474
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 );
484 break;
485
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 );
495 break;
496
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 );
506 break;
507
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 );
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;
529 }// End switch().
530 }// End if().
531 }
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 }
573 }
574
575 add_action( 'admin_notices', '_give_register_admin_notices', - 1 );
576
577
578 /**
579 * Display admin bar when active.
580 *
581 * @param WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
582 *
583 * @return bool
584 */
585 function _give_show_test_mode_notice_in_admin_bar( $wp_admin_bar ) {
586 $is_test_mode = ! empty( $_POST['test_mode'] ) ?
587 give_is_setting_enabled( $_POST['test_mode'] ) :
588 give_is_test_mode();
589
590 if (
591 ! current_user_can( 'view_give_reports' ) ||
592 ! $is_test_mode
593 ) {
594 return false;
595 }
596
597 // Add the main site admin menu item.
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 );
609
610 return true;
611 }
612
613 add_action( 'admin_bar_menu', '_give_show_test_mode_notice_in_admin_bar', 1000, 1 );
614
615 /**
616 * Outputs the Give admin bar CSS.
617 */
618 function _give_test_mode_notice_admin_bar_css() {
619 if ( ! give_is_test_mode() ) {
620 return;
621 }
622 ?>
623 <style>
624 #wpadminbar .give-test-mode-active > .ab-item {
625 color: #fff;
626 background-color: #ffba00;
627 }
628
629 #wpadminbar .give-test-mode-active:hover > .ab-item, #wpadminbar .give-test-mode-active:hover > .ab-item {
630 background-color: rgba(203, 144, 0, 1) !important;
631 color: #fff !important;
632 }
633 </style>
634 <?php
635 }
636
637 add_action( 'admin_head', '_give_test_mode_notice_admin_bar_css' );
638
639
640 /**
641 * Add Link to Import page in from donation archive and donation single page
642 *
643 * @since 1.8.13
644 */
645 function give_import_page_link_callback() {
646 ?>
647 <a href="<?php echo esc_url( give_import_page_url() ); ?>"
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>
665
666 <?php
667 // Check if view donation single page only.
668 if ( ! empty( $_REQUEST['view'] ) && 'view-payment-details' === (string) give_clean( $_REQUEST['view'] ) && 'give-payment-history' === give_clean( $_REQUEST['page'] ) ) {
669 ?>
670 <style type="text/css">
671 .wrap #transaction-details-heading {
672 display: inline-block;
673 }
674 </style>
675 <?php
676 }
677 }
678
679 add_action( 'give_payments_page_top', 'give_import_page_link_callback', 11 );
680
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 /**
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