PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
← All changes | includes/forms/class-charitable-donation-form.php +627 -125 1.6.7 → 1.8.13 View file →
@@ -2,13 +2,13 @@
2 2 /**
3 3 * Donation form model class.
4 4 *
5 5 * @package Charitable/Classes/Charitable_Donation_Form
6 - * @author Eric Daams
7 - * @copyright Copyright (c) 2018, Studio 164a
6 + * @author David Bisset
7 + * @copyright Copyright (c) 2023, WP Charitable LLC
8 8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 9 * @since 1.0.0
10 - * @version 1.6.0
10 + * @version 1.6.60
11 11 */
12 12
13 13 // Exit if accessed directly.
14 14 if ( ! defined( 'ABSPATH' ) ) {
@@ -105,12 +105,22 @@
105 105 */
106 106 protected $valid;
107 107
108 108 /**
109 + * Cached merged fields array.
110 + *
111 + * @since 1.0.0
112 + *
113 + * @var array
114 + */
115 + protected $merged_fields;
116 +
117 + /**
109 118 * Create a donation form object.
110 119 *
111 120 * @since 1.0.0
112 121 * @since 1.5.0 $campaign argument became optional. Previously it was required.
122 + * @since 1.8.2 Added minimum donation amount notice display option.
113 123 *
114 124 * @param Charitable_Campaign|null $campaign Optional. Campaign receiving the donation, or NULL if
115 125 * the campaign will be selected in the form.
116 126 */
@@ -117,13 +127,30 @@
117 127 public function __construct( Charitable_Campaign $campaign = null ) {
118 128 $this->campaign = $campaign;
119 129 $this->id = uniqid();
120 130
131 + // paypal_commerce_connection_check() registers the filters that hide
132 + // PayPal Commerce from the donor-facing gateway list when no seller
133 + // is connected, and that swap the no-active-gateways notice for a
134 + // donor-friendly fallback. Both filters must register BEFORE
135 + // setup_payment_fields() evaluates the active-gateway count — that
136 + // branch only fires (and thus only triggers the friendly fallback)
137 + // when the gateway count drops to zero, which depends on the filter
138 + // already being wired.
139 + $this->paypal_commerce_connection_check();
121 140 $this->setup_payment_fields();
122 141 $this->check_test_mode();
142 + $this->stripe_key_check();
143 + $this->square_connection_check();
123 144
124 145 /* For backwards-compatibility */
125 146 add_action( 'charitable_form_field', array( $this, 'render_field' ), 10, 6 );
147 + /* added in 1.7.0.4 */
148 + if ( 'below_donation_title' === charitable_get_option( 'donation_form_minimal_amount_notice_display', false ) ) {
149 + add_action( 'charitable_after_donation_amount_wrapper_header', array( $this, 'minimum_max_donation_amount_notice' ), 10, 2 );
150 + } elseif ( 'above_donation_title' === charitable_get_option( 'donation_form_minimal_amount_notice_display', false ) || 'after_donation_title' === charitable_get_option( 'donation_form_minimal_amount_notice_display', false ) ) {
151 + add_action( 'charitable_before_donation_amount_wrapper_header', array( $this, 'minimum_max_donation_amount_notice' ), 10, 2 );
152 + }
126 153 }
127 154
128 155 /**
129 156 * Returns the campaign associated with this donation form object.
@@ -137,8 +164,19 @@
137 164 return $this->campaign;
138 165 }
139 166
140 167 /**
168 + * Return the form template, which is the look. Right now, the default is false with "minimal as the beta.
169 + *
170 + * @since 1.8.3.5
171 + *
172 + * @return string
173 + */
174 + public function get_form_template() {
175 + return charitable_get_option( 'donation_form_template', false );
176 + }
177 +
178 + /**
141 179 * Return the current user.
142 180 *
143 181 * @since 1.0.0
144 182 *
@@ -156,8 +194,9 @@
156 194 /**
157 195 * Returns the set value for a particular user field.
158 196 *
159 197 * @since 1.0.0
198 + * @version 1.8.9.1
160 199 *
161 200 * @param string $key The field key.
162 201 * @param string $default Optional. The value that will be used if none is set.
163 202 * @return mixed
@@ -162,11 +201,13 @@
162 201 * @param string $default Optional. The value that will be used if none is set.
163 202 * @return mixed
164 203 */
165 204 public function get_user_value( $key, $default = '' ) {
205 + // phpcs:disable WordPress.Security.NonceVerification.Missing
166 206 if ( isset( $_POST[ $key ] ) ) {
167 - return $_POST[ $key ];
207 + return sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
168 208 }
209 + // phpcs:enable WordPress.Security.NonceVerification.Missing
169 210
170 211 $donation_id = $this->get_validated_donation_id();
171 212
172 213 if ( $donation_id ) {
@@ -284,25 +325,25 @@
284 325 */
285 326 public function get_user_account_fields() {
286 327 $account_fields = array(
287 328 'user_pass' => array(
288 - 'label' => __( 'Password', 'charitable' ),
289 - 'type' => 'password',
290 - 'priority' => 4,
291 - 'required' => true,
329 + 'label' => __( 'Password', 'charitable' ),
330 + 'type' => 'password',
331 + 'priority' => 4,
332 + 'required' => true,
292 333 'requires_registration' => true,
293 - 'data_type' => 'user',
334 + 'data_type' => 'user',
294 335 ),
295 336 );
296 337
297 338 if ( apply_filters( 'charitable_donor_usernames', false ) ) {
298 339 $account_fields['user_login'] = array(
299 - 'label' => __( 'Username', 'charitable' ),
300 - 'type' => 'text',
301 - 'priority' => 2,
302 - 'required' => true,
340 + 'label' => __( 'Username', 'charitable' ),
341 + 'type' => 'text',
342 + 'priority' => 2,
343 + 'required' => true,
303 344 'requires_registration' => true,
304 - 'data_type' => 'user',
345 + 'data_type' => 'user',
305 346 );
306 347 }
307 348
308 349 return $account_fields;
@@ -342,8 +383,9 @@
342 383 /**
343 384 * Return the donation form fields.
344 385 *
345 386 * @since 1.0.0
387 + * @version 1.8.3.5
346 388 *
347 389 * @return array[]
348 390 */
349 391 public function get_fields() {
@@ -348,12 +390,13 @@
348 390 */
349 391 public function get_fields() {
350 392 $fields = array(
351 393 'donation_fields' => array(
352 - 'legend' => __( 'Your Donation', 'charitable' ),
353 - 'type' => 'donation-amount-wrapper',
354 - 'fields' => $this->get_donation_fields(),
355 - 'priority' => 20,
394 + 'legend' => _x( 'Your Donation', 'donation form amount section header', 'charitable' ),
395 + 'type' => 'donation-amount-wrapper',
396 + 'fields' => $this->get_donation_fields(),
397 + 'priority' => 20,
398 + 'multi_currency' => true,
356 399 ),
357 400 'details_fields' => array(
358 401 'legend' => __( 'Details', 'charitable' ),
359 402 'type' => 'details-fields',
@@ -375,8 +418,10 @@
375 418 );
376 419
377 420 $fields = $this->maybe_add_terms_conditions_fields( $fields );
378 421
422 + $fields = $this->maybe_add_minimum_donation_amount( $fields );
423 +
379 424 /**
380 425 * Filter the donation form fields.
381 426 *
382 427 * @since 1.0.0
@@ -405,9 +450,9 @@
405 450 $gateways = array();
406 451 $has_gateway_fields = false;
407 452
408 453 foreach ( $gateways_helper->get_active_gateways() as $gateway_id => $gateway_class ) {
409 - $gateway = new $gateway_class;
454 + $gateway = new $gateway_class();
410 455 $gateway_fields = $this->add_credit_card_fields( array(), $gateway );
411 456
412 457 /**
413 458 * Filter the gateway fields.
@@ -456,12 +501,25 @@
456 501
457 502 $amount = $this->get_campaign()->get_donation_amount_in_session();
458 503
459 504 if ( ! $amount ) {
460 - $content = charitable_template_from_session_content( 'donation_form_current_amount_text', array(
461 - 'campaign_id' => $this->get_campaign()->ID,
462 - 'form_id' => $this->get_form_identifier(),
463 - ), '' );
505 + $content = charitable_template_from_session_content(
506 + 'donation_form_current_amount_text',
507 + array(
508 + 'campaign_id' => $this->get_campaign()->ID,
509 + 'form_id' => $this->get_form_identifier(),
510 + ),
511 + ''
512 + );
513 + } elseif ( defined( 'CHARITABLE_DISABLE_SHOW_CURRENT_DONATION_AMOUNT' ) && CHARITABLE_DISABLE_SHOW_CURRENT_DONATION_AMOUNT ) {
514 + $content = charitable_template_from_session_content(
515 + 'donation_form_current_amount_text',
516 + array(
517 + 'campaign_id' => $this->get_campaign()->ID,
518 + 'form_id' => $this->get_form_identifier(),
519 + ),
520 + ''
521 + );
464 522 } else {
465 523 $content = charitable_template_donation_form_current_amount_text( $amount, $this->get_form_identifier(), $this->get_campaign()->ID );
466 524 }
467 525
@@ -487,17 +545,22 @@
487 545
488 546 /**
489 547 * Render the donation form.
490 548 *
491 - * @since 1.0.0
549 + * @since 1.0.0
550 + * @version 1.8.3.6 added get_form_template()
492 551 *
493 552 * @return void
494 553 */
495 554 public function render() {
496 - charitable_template( 'donation-form/form-donation.php', array(
497 - 'campaign' => $this->get_campaign(),
498 - 'form' => $this,
499 - ) );
555 + charitable_template(
556 + 'donation-form/form-donation.php',
557 + array(
558 + 'campaign' => $this->get_campaign(),
559 + 'form_template' => $this->get_form_template(),
560 + 'form' => $this,
561 + )
562 + );
500 563 }
501 564
502 565 /**
503 566 * Return the validated donation ID.
@@ -506,19 +569,23 @@
506 569 * the donation ID is checked to ensure it corresponds to a donation
507 570 * and one that the current user should have access to.
508 571 *
509 572 * @since 1.5.14
573 + * @version 1.8.9.1
510 574 *
511 575 * @return int
512 576 */
513 577 public function get_validated_donation_id() {
578 + // phpcs:disable WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
514 579 if ( array_key_exists( 'donation_id', $_GET ) ) {
515 - $donation_id = $_GET['donation_id'];
580 + $donation_id = intval( wp_unslash( $_GET['donation_id'] ) );
516 581 } elseif ( array_key_exists( 'ID', $_POST ) ) {
517 - $donation_id = $_POST['ID'];
582 + $donation_id = intval( wp_unslash( $_POST['ID'] ) );
518 583 } else {
584 + // phpcs:enable WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
519 585 return 0;
520 586 }
587 + // phpcs:enable WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
521 588
522 589 if ( charitable_user_can_access_donation( $donation_id ) ) {
523 590 return $donation_id;
524 591 }
@@ -641,13 +708,22 @@
641 708 public function validate_security_check() {
642 709 $ret = true;
643 710
644 711 if ( ! $this->validate_nonce() || ! $this->validate_honeypot() ) {
712 + charitable_get_notices()->add_error(
713 + __( 'Unfortunately, we were unable to verify your form submission. Please reload the page and try again.', 'charitable' )
714 + );
645 715
646 - charitable_get_notices()->add_error( __( 'There was an error with processing your form submission. Please reload the page and try again.', 'charitable' ) );
716 + // Log the security validation failure
717 + $error_details = ! $this->validate_nonce() ? 'nonce_failed' : 'honeypot_failed';
718 + $context = array(
719 + 'campaign_id' => $this->campaign ? $this->campaign->ID : 0,
720 + 'amount' => $this->get_submitted_value( 'donation_amount' ),
721 + 'gateway' => $this->get_submitted_value( 'gateway' ),
722 + );
723 + charitable_log_form_error( 'security_failure', $error_details, $context );
647 724
648 725 $ret = false;
649 -
650 726 }
651 727
652 728 /**
653 729 * Filter the security validation result.
@@ -670,15 +746,26 @@
670 746 public function validate_email() {
671 747 $ret = true;
672 748
673 749 /* Don't process donations with dummy emails. */
674 - if ( array_key_exists( 'email', $_POST ) && ! is_email( $_POST['email'] ) ) {
675 - charitable_get_notices()->add_error( sprintf(
750 + $submitted = $this->get_submitted_value( 'email' );
751 + if ( ! is_null( $submitted ) && ! is_email( $submitted ) ) {
752 + charitable_get_notices()->add_error(
753 + sprintf(
676 754 /* translators: %s: email address */
677 - __( '%s is not a valid email address.', 'charitable' ),
678 - $_POST['email']
679 - ) );
755 + __( '%s is not a valid email address.', 'charitable' ),
756 + $submitted
757 + )
758 + );
680 759
760 + // Log the email validation failure
761 + $context = array(
762 + 'campaign_id' => $this->campaign ? $this->campaign->ID : 0,
763 + 'amount' => $this->get_submitted_value( 'donation_amount' ),
764 + 'gateway' => $this->get_submitted_value( 'gateway' ),
765 + );
766 + charitable_log_form_error( 'validation_failure', 'invalid_email', $context );
767 +
681 768 $ret = false;
682 769 }
683 770
684 771 /**
@@ -699,18 +786,14 @@
699 786 *
700 787 * @return boolean
701 788 */
702 789 public function validate_gateway() {
703 -
704 790 $ret = true;
705 791
706 792 /* Validate the gateway. */
707 - if ( ! Charitable_Gateways::get_instance()->is_valid_gateway( $_POST['gateway'] ) ) {
708 -
793 + if ( ! Charitable_Gateways::get_instance()->is_valid_gateway( $this->get_submitted_value( 'gateway' ) ) ) {
709 794 charitable_get_notices()->add_error( __( 'The gateway submitted is not valid.', 'charitable' ) );
710 -
711 795 $ret = false;
712 -
713 796 }
714 797
715 798 /**
716 799 * Filter the gateway validation result.
@@ -720,9 +803,8 @@
720 803 * @param boolean $ret The result to be returned. True or False.
721 804 * @param Charitable_Donation_Form $form This instance of `Charitable_Donation_Form`.
722 805 */
723 806 return apply_filters( 'charitable_validate_donation_form_submission_gateway_check', $ret, $this );
724 -
725 807 }
726 808
727 809 /**
728 810 * Checks whether the set amount is valid.
@@ -734,25 +816,67 @@
734 816 public function validate_amount() {
735 817 $ret = true;
736 818
737 819 /* Ensure that a valid amount has been submitted. */
738 - $minimum = charitable_get_minimum_donation_amount();
739 - $amount = self::get_donation_amount();
820 + $submitted = $this->get_submitted_values();
821 + $minimum = charitable_get_minimum_donation_amount( $submitted['campaign_id'] );
822 + $maximum = charitable_get_maximum_donation_amount( $submitted['campaign_id'] );
823 + $amount = self::get_donation_amount();
740 824
741 825 if ( $minimum > 0 && $amount < $minimum ) {
742 - charitable_get_notices()->add_error( sprintf(
743 - __( 'You must donate more than %s.', 'charitable' ),
744 - charitable_format_money( $minimum )
745 - ) );
826 + charitable_get_notices()->add_error(
827 + sprintf(
828 + /* translators: %s: minimum donation amount */
829 + __( 'You must donate more than %s.', 'charitable' ),
830 + charitable_format_money( $minimum, false, true )
831 + )
832 + );
746 833
834 + // Log the minimum amount validation failure
835 + $context = array(
836 + 'campaign_id' => $submitted['campaign_id'],
837 + 'amount' => $amount,
838 + 'gateway' => $this->get_submitted_value( 'gateway' ),
839 + );
840 + charitable_log_form_error( 'validation_failure', 'amount_below_minimum', $context );
841 +
747 842 $ret = false;
748 - } elseif ( $minimum == 0 && $amount <= 0 && ! apply_filters( 'charitable_permit_0_donation', false ) ) {
749 - charitable_get_notices()->add_error( sprintf(
750 - __( 'You must donate more than %s.', 'charitable' ),
751 - charitable_format_money( $minimum )
752 - ) );
843 + } elseif ( $maximum && $maximum < $amount ) {
844 + charitable_get_notices()->add_error(
845 + sprintf(
846 + /* translators: %s: maximum donation amount */
847 + __( 'The maximum donation amount permitted is %s.', 'charitable' ),
848 + charitable_format_money( $maximum, false, true )
849 + )
850 + );
753 851
852 + // Log the maximum amount validation failure
853 + $context = array(
854 + 'campaign_id' => $submitted['campaign_id'],
855 + 'amount' => $amount,
856 + 'gateway' => $this->get_submitted_value( 'gateway' ),
857 + );
858 + charitable_log_form_error( 'validation_failure', 'amount_above_maximum', $context );
859 +
754 860 $ret = false;
861 + } elseif ( $minimum === 0 && $amount <= 0 && ! apply_filters( 'charitable_permit_0_donation', false ) ) {
862 + charitable_get_notices()->add_error(
863 + sprintf(
864 + /* translators: %s: minimum donation amount */
865 + __( 'You must donate more than %s.', 'charitable' ),
866 + charitable_format_money( $minimum )
867 + )
868 + );
869 +
870 + // Log the zero amount validation failure
871 + $context = array(
872 + 'campaign_id' => $submitted['campaign_id'],
873 + 'amount' => $amount,
874 + 'gateway' => $this->get_submitted_value( 'gateway' ),
875 + );
876 + charitable_log_form_error( 'validation_failure', 'zero_amount_not_permitted', $context );
877 +
878 + $ret = false;
755 879 }
756 880
757 881 /**
758 882 * Filter the amount validation result.
@@ -762,9 +886,8 @@
762 886 * @param boolean $ret The result to be returned. True or False.
763 887 * @param Charitable_Donation_Form $form This instance of `Charitable_Donation_Form`.
764 888 */
765 889 return apply_filters( 'charitable_validate_donation_form_submission_amount_check', $ret, $this );
766 -
767 890 }
768 891
769 892 /**
770 893 * Return the donation values.
@@ -791,17 +914,12 @@
791 914 $values['donation_key'] = charitable_get_donation( $values['ID'] )->get_donation_key();
792 915 }
793 916
794 917 foreach ( $this->get_merged_fields() as $key => $field ) {
795 -
796 918 if ( isset( $field['data_type'] ) || 'gateways' == $key ) {
797 -
798 919 if ( 'gateways' == $key ) {
799 -
800 920 foreach ( $field as $gateway_id => $gateway_fields ) {
801 -
802 921 foreach ( $gateway_fields as $key => $field ) {
803 -
804 922 if ( ! isset( $field['type'] ) ) {
805 923 continue;
806 924 }
807 925
@@ -817,15 +935,13 @@
817 935 $values['gateways'][ $gateway_id ][ $key ] = $value;
818 936 }
819 937 }
820 938 } elseif ( isset( $field['type'] ) ) {
821 -
822 939 $data_type = $field['data_type'];
823 940 $field_type = $field['type'];
824 941 $default = 'checkbox' == $field_type ? false : '';
825 942
826 943 $values[ $data_type ][ $key ] = isset( $submitted[ $key ] ) ? $submitted[ $key ] : $default;
827 -
828 944 }
829 945 }
830 946 }
831 947
@@ -848,15 +964,17 @@
848 964 *
849 965 * @return array[]
850 966 */
851 967 public function get_merged_fields() {
852 - $fields = array();
968 + if ( ! isset( $this->merged_fields ) ) {
969 + $this->merged_fields = array();
853 970
854 - foreach ( $this->get_fields() as $section_id => $section ) {
855 - $fields = array_merge( $fields, $this->get_fields_from_section( $section_id, $section ) );
971 + foreach ( $this->get_fields() as $section_id => $section ) {
972 + $this->merged_fields = array_merge( $this->merged_fields, $this->get_fields_from_section( $section_id, $section ) );
973 + }
856 974 }
857 975
858 - return $fields;
976 + return $this->merged_fields;
859 977 }
860 978
861 979 /**
862 980 * Return the fields from a particular section.
@@ -924,8 +1042,90 @@
924 1042 return $this->user_has_required_fields;
925 1043 }
926 1044
927 1045 /**
1046 + * Maybe add minimum donation message to form.
1047 + *
1048 + * @since 1.7.0.4
1049 + *
1050 + * @param array $fields The registered donation form fields.
1051 + * @return array
1052 + */
1053 + public function maybe_add_minimum_donation_amount( $fields ) {
1054 +
1055 + if ( false === $this->get_campaign()->ID || false === $fields || ! isset( $fields['donation_fields']['fields'] ) ) {
1056 + return $fields;
1057 + }
1058 +
1059 + if ( false === charitable_get_option( 'donation_form_minimal_amount_notice_display', false ) || 'below_amount_selection' !== charitable_get_option( 'donation_form_minimal_amount_notice_display', false ) ) {
1060 + return $fields;
1061 + }
1062 +
1063 + $terms_fields = array();
1064 + $minimum_amount = get_post_meta( $this->get_campaign()->ID, '_campaign_minimum_donation_amount', true );
1065 +
1066 + // do not display a message in the donation form if the field is zero or empty.
1067 + if ( false === $minimum_amount || '' === trim( $minimum_amount ) ) {
1068 + return $fields;
1069 + }
1070 +
1071 + // default location of the minimum donation amount.
1072 + $fields['donation_fields']['fields']['minimum_donation_amount'] = array(
1073 + 'legend' => __( 'Mininum Donation', 'charitable' ),
1074 + 'type' => 'content',
1075 + 'content' => $this->minimum_max_donation_amount_notice( true, $minimum_amount ),
1076 + 'priority' => 80,
1077 + );
1078 +
1079 + /**
1080 + * Filter the minimum donation notification fields.
1081 + *
1082 + * @since 1.7.0.3
1083 + *
1084 + * @param array $terms_fields List of terms fields.
1085 + * @param Charitable_Donation_Form $form Instance of `Charitable_Donation_Form`.
1086 + */
1087 + $minimum_fields = apply_filters( 'charitable_donation_minimum_fields', $fields, $this );
1088 +
1089 + if ( empty( $minimum_fields ) ) {
1090 + return $fields;
1091 + }
1092 +
1093 + return $fields;
1094 + }
1095 +
1096 +
1097 + /**
1098 + * Generate minimum donation notice (with filter for changing text more easily).
1099 + *
1100 + * @since 1.8.0
1101 + *
1102 + * @param string $return False if echo, true if return.
1103 + * @param string $minimum_amount Minimum amount likely set by user in admin settings.
1104 + * @return array
1105 + */
1106 + public function minimum_max_donation_amount_notice( $return = true, $minimum_amount = false ) {
1107 +
1108 + if ( false === $minimum_amount ) {
1109 + $minimum_amount = get_post_meta( $this->get_campaign()->ID, '_campaign_minimum_donation_amount', true );
1110 + }
1111 +
1112 + // do not display a message in the donation form if the field is zero or empty.
1113 + if ( false === $minimum_amount || '' === trim( $minimum_amount ) || 0 === intval( $minimum_amount ) ) {
1114 + return '';
1115 + } else {
1116 + $message = apply_filters( 'charitable_donationa_amount_notice', '<p class="minimum-donation-amount-text">' . __( 'The minimum donation for this campaign is ', 'charitable' ) . charitable_format_money( $minimum_amount, false, true ) . '.</p>', $minimum_amount );
1117 + }
1118 +
1119 + if ( $return ) {
1120 + return $message;
1121 + } else {
1122 + echo $message; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1123 + }
1124 + }
1125 +
1126 +
1127 + /**
928 1128 * Maybe add terms and conditions fields to the form.
929 1129 *
930 1130 * @since 1.6.0
931 1131 *
@@ -933,40 +1133,38 @@
933 1133 * @return array
934 1134 */
935 1135 public function maybe_add_terms_conditions_fields( $fields ) {
936 1136 $terms_fields = array();
937 - $privacy_page = (int) charitable_get_option( 'privacy_policy_page', 0 );
938 - $terms_page = (int) charitable_get_option( 'terms_conditions_page', 0 );
939 1137 $show_consent = (int) charitable_get_option( 'contact_consent', 0 ) && Charitable_Upgrade::get_instance()->upgrade_has_been_completed( 'upgrade_donor_tables' );
940 1138
941 - if ( $privacy_page ) {
1139 + if ( charitable_is_privacy_policy_activated() ) {
942 1140 $terms_fields['privacy_policy_text'] = array(
943 1141 'type' => 'content',
944 - 'content' => '<p class="charitable-privacy-policy-text">' . $this->get_parsed_privacy_text( $privacy_page ) . '</p>',
1142 + 'content' => '<p class="charitable-privacy-policy-text">' . charitable_get_privacy_policy_field_text() . '</p>',
945 1143 'priority' => 4,
946 1144 );
947 1145 }
948 1146
949 - if ( $show_consent ) {
1147 + if ( charitable_is_contact_consent_activated() ) {
950 1148 $terms_fields['contact_consent'] = array(
951 1149 'type' => 'checkbox',
952 1150 'label' => charitable_get_option( 'contact_consent_label', __( 'Yes, I am happy for you to contact me via email or phone.', 'charitable' ) ),
953 1151 'priority' => 8,
954 - 'required' => false,
1152 + 'required' => charitable_get_option( 'contact_consent_required', false ),
955 1153 'data_type' => 'meta',
956 1154 );
957 1155 }
958 1156
959 - if ( $terms_page ) {
1157 + if ( charitable_is_terms_and_conditions_activated() ) {
960 1158 $terms_fields['terms_text'] = array(
961 1159 'type' => 'content',
962 - 'content' => '<div class="charitable-terms-text">' . $this->get_terms( $terms_page ) . '</div>',
1160 + 'content' => '<div class="charitable-terms-text">' . charitable_get_terms_and_conditions() . '</div>',
963 1161 'priority' => 12,
964 1162 );
965 1163
966 1164 $terms_fields['accept_terms'] = array(
967 1165 'type' => 'checkbox',
968 - 'label' => $this->get_parsed_terms_text( $terms_page ),
1166 + 'label' => charitable_get_terms_and_conditions_field_label(),
969 1167 'priority' => 16,
970 1168 'required' => true,
971 1169 'data_type' => 'meta',
972 1170 );
@@ -985,80 +1183,86 @@
985 1183 if ( empty( $terms_fields ) ) {
986 1184 return $fields;
987 1185 }
988 1186
989 - return array_merge( $fields, array(
990 - 'terms_fields' => array(
991 - 'legend' => __( 'Terms and Conditions', 'charitable' ),
992 - 'type' => 'fieldset',
993 - 'fields' => $terms_fields,
994 - 'priority' => 80,
995 - ),
996 - ) );
1187 + return array_merge(
1188 + $fields,
1189 + array(
1190 + 'terms_fields' => array(
1191 + 'legend' => __( 'Terms and Conditions', 'charitable' ),
1192 + 'type' => 'fieldset',
1193 + 'fields' => $terms_fields,
1194 + // Terms must be accepted before the donor commits to
1195 + // a payment method, so order this fieldset just above
1196 + // the Payment fieldset (priority 60). Donors see
1197 + // consent → payment, not payment → consent.
1198 + 'priority' => 56,
1199 + ),
1200 + )
1201 + );
997 1202 }
998 1203
999 1204 /**
1000 1205 * Return the terms and conditions text.
1001 1206 *
1207 + * @deprecated 2.0.0
1208 + *
1002 1209 * @since 1.6.0
1210 + * @since 1.6.14 Deprecated.
1003 1211 *
1004 1212 * @param int $terms_page The ID of the terms page.
1005 1213 * @return string
1006 1214 */
1007 1215 public function get_terms( $terms_page ) {
1008 - remove_filter( 'the_content', array( charitable()->endpoints(), 'get_content' ) );
1216 + charitable_get_deprecated()->deprecated_function(
1217 + __METHOD__,
1218 + '1.6.14',
1219 + 'charitable_get_terms_and_conditions'
1220 + );
1009 1221
1010 - $content = apply_filters( 'the_content', get_post_field( 'post_content', $terms_page, 'display' ) );
1011 -
1012 - add_filter( 'the_content', array( charitable()->endpoints(), 'get_content' ) );
1013 -
1014 - return $content;
1222 + return charitable_get_terms_and_conditions();
1015 1223 }
1016 1224
1017 1225 /**
1018 1226 * Return the terms text, with [terms] replaced by a link to the terms and conditions.
1019 1227 *
1228 + * @deprecated 2.0.0
1229 + *
1020 1230 * @since 1.6.0
1231 + * @since 1.6.14 Deprecated.
1021 1232 *
1022 1233 * @param int $terms_page The ID of the terms page.
1023 1234 * @return string
1024 1235 */
1025 1236 public function get_parsed_terms_text( $terms_page ) {
1026 - $url = get_the_permalink( $terms_page );
1237 + charitable_get_deprecated()->deprecated_function(
1238 + __METHOD__,
1239 + '1.6.14',
1240 + 'charitable_get_terms_and_conditions_field_label'
1241 + );
1027 1242
1028 - if ( ! $url ) {
1029 - return '';
1030 - }
1031 -
1032 - $text = charitable_get_option( 'terms_conditions', __( 'I have read and agree to the website [terms].', 'charitable' ) );
1033 - $replace = sprintf( '<a href="%s" target="_blank" class="charitable-terms-link">%s</a>',
1034 - $url,
1035 - __( 'terms and conditions', 'charitable' )
1036 - );
1037 - return str_replace( '[terms]', $replace, $text );
1243 + return charitable_get_terms_and_conditions_field_label();
1038 1244 }
1039 1245
1040 1246 /**
1041 1247 * Return the privacy policy text, with [privacy_policy] replaced by a link to the privacy policy page.
1042 1248 *
1249 + * @deprecated 2.0.0
1250 + *
1043 1251 * @since 1.6.0
1252 + * @since 1.6.14 Deprecated.
1044 1253 *
1045 1254 * @param int $privacy_page The ID of the privacy policy page.
1046 1255 * @return string
1047 1256 */
1048 1257 public function get_parsed_privacy_text( $privacy_page ) {
1049 - $url = get_the_permalink( $privacy_page );
1258 + charitable_get_deprecated()->deprecated_function(
1259 + __METHOD__,
1260 + '1.6.14',
1261 + 'charitable_get_privacy_policy_field_text'
1262 + );
1050 1263
1051 - if ( ! $url ) {
1052 - return '';
1053 - }
1054 -
1055 - $text = charitable_get_option( 'privacy_policy', __( 'Your personal data will be used to process your donation, support your experience throughout this website, and for other purposes described in our [privacy_policy].', 'charitable' ) );
1056 - $replace = sprintf( '<a href="%s" target="_blank" class="charitable-privacy-policy-link">%s</a>',
1057 - $url,
1058 - __( 'privacy policy', 'charitable' )
1059 - );
1060 - return str_replace( '[privacy_policy]', $replace, $text );
1264 + return charitable_get_privacy_policy_field_text();
1061 1265 }
1062 1266
1063 1267 /**
1064 1268 * Returns whether the form should hide the user fields.
@@ -1084,20 +1288,38 @@
1084 1288 /**
1085 1289 * Return the donation amount.
1086 1290 *
1087 1291 * @since 1.0.0
1292 + * @version 1.8.9.1
1088 1293 *
1089 1294 * @return float
1090 1295 */
1091 1296 public static function get_donation_amount() {
1092 - $amount = isset( $_POST['donation_amount'] ) ? $_POST['donation_amount'] : 0;
1297 + // phpcs:disable WordPress.Security.NonceVerification.Missing
1298 + $amount = isset( $_POST['donation_amount'] ) ? sanitize_text_field( wp_unslash( $_POST['donation_amount'] ) ) : 0;
1093 1299
1094 1300 if ( 0 === $amount || 'custom' == $amount ) {
1095 - $amount = isset( $_POST['custom_donation_amount'] ) ? $_POST['custom_donation_amount'] : 0;
1301 + $amount = isset( $_POST['custom_donation_amount'] ) ? sanitize_text_field( wp_unslash( $_POST['custom_donation_amount'] ) ) : 0;
1096 1302 }
1303 + // phpcs:enable WordPress.Security.NonceVerification.Missing
1097 1304
1098 - $amount = charitable_get_currency_helper()->sanitize_monetary_amount( (string) $amount );
1305 + /**
1306 + * Only sanitize the amount if it's a number (no letters).
1307 + *
1308 + * With Recurring Donations, it's possible that amount might be 'recurring-custom',
1309 + * which should not be sanitized.
1310 + */
1311 + if ( ! is_string( $amount ) || ! preg_match( '/[A-Za-z]/', $amount ) ) {
1312 + $amount = charitable_get_currency_helper()->sanitize_monetary_amount( (string) $amount );
1313 + }
1099 1314
1315 + /**
1316 + * Filter the donation amount.
1317 + *
1318 + * @since 1.3.0
1319 + *
1320 + * @param float|WP_Error $amount The donation amount.
1321 + */
1100 1322 return apply_filters( 'charitable_donation_form_amount', $amount );
1101 1323 }
1102 1324
1103 1325 /**
@@ -1127,8 +1349,9 @@
1127 1349 /**
1128 1350 * Set a field's initial value.
1129 1351 *
1130 1352 * @since 1.5.0
1353 + * @version 1.8.9.1
1131 1354 *
1132 1355 * @param array $field Field definition.
1133 1356 * @param string $key The key of the field.
1134 1357 * @return array
@@ -1134,11 +1357,23 @@
1134 1357 * @return array
1135 1358 */
1136 1359 protected function set_field_value( $field, $key ) {
1137 1360 $donation_id = $this->get_validated_donation_id();
1361 + // phpcs:disable WordPress.Security.NonceVerification.Missing
1362 + $submitted = isset( $_POST[ $key ] ) ? sanitize_text_field( wp_unslash( $_POST[ $key ] ) ) : null;
1363 + // phpcs:enable WordPress.Security.NonceVerification.Missing
1138 1364
1139 - if ( array_key_exists( $key, $_POST ) ) {
1140 - $field['value'] = $_POST[ $key ];
1365 + /* Mark a checkbox as checked. */
1366 + if ( 'checkbox' === $field['type'] ) {
1367 + $checked_value = isset( $field['value'] ) ? $field['value'] : 1;
1368 +
1369 + if ( ! is_null( $submitted ) ) {
1370 + $field['checked'] = $submitted == $checked_value;
1371 + } elseif ( $donation_id ) {
1372 + $field['checked'] = charitable_get_donation( $donation_id )->get( $key ) == $checked_value;
1373 + }
1374 + } elseif ( ! is_null( $submitted ) ) {
1375 + $field['value'] = $submitted;
1141 1376 } elseif ( $donation_id ) {
1142 1377 $donation = charitable_get_donation( $donation_id );
1143 1378 $field['value'] = $donation ? $donation->get( $key ) : '';
1144 1379 }
@@ -1213,10 +1448,11 @@
1213 1448 * @return string
1214 1449 */
1215 1450 protected function get_test_mode_active_notice() {
1216 1451 $notice = $this->get_credentialed_notice(
1217 - __( 'Test mode is active.', 'charitable' ),
1218 - sprintf( '<a href="%s">%s</a>.',
1452 + __( 'Test mode is enabled.', 'charitable' ),
1453 + sprintf(
1454 + '<a href="%s">%s</a>.',
1219 1455 admin_url( 'admin.php?page=charitable-settings&tab=gateways' ),
1220 1456 __( 'Disable Test Mode', 'charitable' )
1221 1457 )
1222 1458 );
@@ -1224,8 +1460,272 @@
1224 1460 return apply_filters( 'charitable_test_mode_active_notice', $notice, current_user_can( 'manage_charitable_settings' ) );
1225 1461 }
1226 1462
1227 1463 /**
1464 + * Determine if there is a Stripe key set if Stripe is a payment gateway
1465 + *
1466 + * @since 1.8.2
1467 + *
1468 + * @return void
1469 + */
1470 + protected function stripe_key_check() {
1471 +
1472 + if ( defined( 'CHARITABLE_DISABLE_STRIPE_KEY_CHECK' ) && CHARITABLE_DISABLE_STRIPE_KEY_CHECK ) {
1473 + return;
1474 + }
1475 +
1476 + if ( ! class_exists( 'Charitable_Gateway_Stripe_AM' ) ) {
1477 + return;
1478 + }
1479 +
1480 + $active_gateways = charitable_get_helper( 'gateways' )->get_active_gateways();
1481 + $has_gateways = apply_filters( 'charitable_has_active_gateways', ! empty( $active_gateways ) );
1482 +
1483 + if ( ! $has_gateways ) {
1484 + return;
1485 + }
1486 +
1487 + if ( ! is_array( $active_gateways ) || ! in_array( 'Charitable_Gateway_Stripe_AM', $active_gateways ) ) {
1488 + return;
1489 + }
1490 +
1491 + // Stripe is enabled, check if the keys are set.
1492 + $gateway = new Charitable_Gateway_Stripe_AM();
1493 + $keys = $gateway->get_keys();
1494 +
1495 + // If there is no public key, and current user is an admin, display an alert on the form. */
1496 + if ( ( ! isset( $keys['public_key'] ) || empty( $keys['public_key'] ) ) && current_user_can( 'manage_charitable_settings' ) ) {
1497 + charitable_get_notices()->add_error( $this->get_stripe_key_check_notice() );
1498 + }
1499 + }
1500 +
1501 + /**
1502 + * A formatted notice to advise that Test Mode is active.
1503 + *
1504 + * @since 1.8.2
1505 + *
1506 + * @return string
1507 + */
1508 + protected function get_stripe_key_check_notice() {
1509 + $notice = $this->get_credentialed_notice(
1510 + __( 'Stripe is enabled but some keys are missing.', 'charitable' ),
1511 + sprintf(
1512 + '<a href="%s">%s</a>.',
1513 + admin_url( 'admin.php?page=charitable-settings&tab=gateways&group=gateways_stripe' ),
1514 + __( 'View Settings', 'charitable' )
1515 + )
1516 + );
1517 +
1518 + return apply_filters( 'charitable_stripe_key_check_notice', $notice, current_user_can( 'manage_charitable_settings' ) );
1519 + }
1520 +
1521 + /**
1522 + * Check if Square connection is available for the current mode.
1523 + *
1524 + * @since 1.8.5
1525 + *
1526 + * @return void
1527 + */
1528 + protected function square_connection_check() {
1529 + // Check if there's a Square mode connection warning
1530 + $warning = get_option( 'charitable_square_mode_connection_warning' );
1531 +
1532 + if ( ! $warning ) {
1533 + return;
1534 + }
1535 +
1536 + // Check if Square gateway is active
1537 + $active_gateways = charitable_get_helper( 'gateways' )->get_active_gateways();
1538 +
1539 + if ( ! is_array( $active_gateways ) || ! in_array( 'Charitable_Gateway_Square', $active_gateways ) ) {
1540 + return;
1541 + }
1542 +
1543 + // Only show warning to admins
1544 + if ( ! current_user_can( 'manage_charitable_settings' ) ) {
1545 + return;
1546 + }
1547 +
1548 + // Display the warning
1549 + charitable_get_notices()->add_error( $this->get_square_connection_warning_notice( $warning['mode'] ) );
1550 + }
1551 +
1552 + /**
1553 + * A formatted notice to advise that Square connection is missing for the current mode.
1554 + *
1555 + * @since 1.8.5
1556 + *
1557 + * @param string $mode The mode that's missing connection.
1558 + * @return string
1559 + */
1560 + protected function get_square_connection_warning_notice( $mode ) {
1561 + $mode_label = 'test' === $mode ? __( 'test', 'charitable' ) : __( 'live', 'charitable' );
1562 +
1563 + $notice = $this->get_credentialed_notice(
1564 + sprintf(
1565 + /* translators: %s: mode (test or live) */
1566 + __( 'Square is enabled but not connected in %s mode.', 'charitable' ),
1567 + $mode_label
1568 + ),
1569 + sprintf(
1570 + '<a href="%s">%s</a>.',
1571 + admin_url( 'admin.php?page=charitable-settings&tab=gateways&group=gateways_square_core' ),
1572 + __( 'Connect Square Account', 'charitable' )
1573 + )
1574 + );
1575 +
1576 + return apply_filters( 'charitable_square_connection_warning_notice', $notice, current_user_can( 'manage_charitable_settings' ) );
1577 + }
1578 +
1579 + /**
1580 + * Tracks whether the donor-facing payment list was stripped of
1581 + * PayPal Commerce because the seller account wasn't connected.
1582 + * Drives the donor-facing "donations temporarily unavailable"
1583 + * message when this is the only reason there are no gateways.
1584 + *
1585 + * @since 1.8.11
1586 + * @var bool
1587 + */
1588 + protected static $paypal_commerce_hidden_for_disconnect = false;
1589 +
1590 + /**
1591 + * Determine PayPal Commerce's connection status and warn admins when
1592 + * the gateway is enabled but no PayPal account is connected.
1593 + *
1594 + * Also wires the runtime filters that:
1595 + * - hide PayPal Commerce from the donor-facing payment list when
1596 + * it's not connected, so donors never see a broken option, and
1597 + * - swap the generic "no active payment gateways" notice for a
1598 + * donor-friendly "temporarily unavailable" message when PayPal
1599 + * was the only enabled gateway.
1600 + *
1601 + * Donors never see the admin notice — capability-gated through
1602 + * get_credentialed_notice() — but they do see the donor-side
1603 + * graceful message.
1604 + *
1605 + * @since 1.8.11
1606 + *
1607 + * @return void
1608 + */
1609 + protected function paypal_commerce_connection_check() {
1610 + if ( defined( 'CHARITABLE_DISABLE_PAYPAL_COMMERCE_CHECK' ) && CHARITABLE_DISABLE_PAYPAL_COMMERCE_CHECK ) {
1611 + return;
1612 + }
1613 +
1614 + if ( ! class_exists( 'Charitable_Gateway_Paypal_Commerce' ) ) {
1615 + return;
1616 + }
1617 +
1618 + $active_gateways = charitable_get_helper( 'gateways' )->get_active_gateways();
1619 + $has_gateways = apply_filters( 'charitable_has_active_gateways', ! empty( $active_gateways ) );
1620 +
1621 + if ( ! $has_gateways ) {
1622 + return;
1623 + }
1624 +
1625 + if ( ! is_array( $active_gateways ) || ! array_key_exists( 'paypal_commerce', $active_gateways ) ) {
1626 + return;
1627 + }
1628 +
1629 + $gateway = new Charitable_Gateway_Paypal_Commerce();
1630 +
1631 + if ( $gateway->is_seller_connected() ) {
1632 + return;
1633 + }
1634 +
1635 + // Wire the runtime filters once per request — gateway list cleanup
1636 + // and the donor-friendly fallback notice.
1637 + add_filter( 'charitable_active_gateways', array( $this, 'filter_active_gateways_hide_disconnected_paypal_commerce' ) );
1638 + add_filter( 'charitable_no_active_gateways_notice', array( $this, 'filter_no_active_gateways_notice_when_paypal_disconnected' ), 10, 2 );
1639 +
1640 + // Admin-only notice in the form-level error list (matches Stripe pattern).
1641 + if ( current_user_can( 'manage_charitable_settings' ) ) { // phpcs:ignore
1642 + charitable_get_notices()->add_error( $this->get_paypal_commerce_connection_check_notice() );
1643 + }
1644 + }
1645 +
1646 + /**
1647 + * Build the admin-only notice text for the PayPal Commerce
1648 + * "enabled but not connected" state. Donors never see this — the
1649 + * admin-action link is only appended when the current user can
1650 + * manage Charitable settings.
1651 + *
1652 + * @since 1.8.11
1653 + *
1654 + * @return string
1655 + */
1656 + protected function get_paypal_commerce_connection_check_notice() {
1657 + $notice = $this->get_credentialed_notice(
1658 + __( 'PayPal Commerce is enabled but no PayPal account is connected.', 'charitable' ),
1659 + sprintf(
1660 + '<a href="%s">%s</a>.',
1661 + admin_url( 'admin.php?page=charitable-settings&tab=gateways&group=gateways_paypal_commerce' ),
1662 + __( 'Connect with PayPal', 'charitable' )
1663 + )
1664 + );
1665 +
1666 + return apply_filters( 'charitable_paypal_commerce_connection_check_notice', $notice, current_user_can( 'manage_charitable_settings' ) ); // phpcs:ignore
1667 + }
1668 +
1669 + /**
1670 + * Remove PayPal Commerce from the active gateway list when its seller
1671 + * isn't connected. Donors then never see the option on the donation
1672 + * form, and the gateway-selector form field doesn't render a broken
1673 + * radio that would have failed at PayPal-side anyway.
1674 + *
1675 + * Flips $paypal_commerce_hidden_for_disconnect so the companion
1676 + * `charitable_no_active_gateways_notice` filter can swap the
1677 + * standard message for the donor-friendly variant when PayPal was
1678 + * the only enabled gateway.
1679 + *
1680 + * @since 1.8.11
1681 + *
1682 + * @param array $gateways Active gateway map (gateway_id => class name).
1683 + * @return array
1684 + */
1685 + public function filter_active_gateways_hide_disconnected_paypal_commerce( $gateways ) {
1686 + if ( ! is_array( $gateways ) || ! array_key_exists( 'paypal_commerce', $gateways ) ) {
1687 + return $gateways;
1688 + }
1689 +
1690 + unset( $gateways['paypal_commerce'] );
1691 + self::$paypal_commerce_hidden_for_disconnect = true;
1692 +
1693 + return $gateways;
1694 + }
1695 +
1696 + /**
1697 + * Replace the "no active payment gateways" message with a
1698 + * donor-friendly fallback when PayPal Commerce is the only
1699 + * enabled gateway and we just stripped it for being disconnected.
1700 + * Admins still get an actionable link; donors see graceful copy.
1701 + *
1702 + * @since 1.8.11
1703 + *
1704 + * @param string $notice Default notice text.
1705 + * @param bool $is_admin Whether the current user can manage Charitable settings.
1706 + * @return string
1707 + */
1708 + public function filter_no_active_gateways_notice_when_paypal_disconnected( $notice, $is_admin = false ) {
1709 + if ( ! self::$paypal_commerce_hidden_for_disconnect ) {
1710 + return $notice;
1711 + }
1712 +
1713 + if ( $is_admin ) {
1714 + return $this->get_credentialed_notice(
1715 + __( 'PayPal Commerce is enabled but no PayPal account is connected.', 'charitable' ),
1716 + sprintf(
1717 + '<a href="%s">%s</a>.',
1718 + admin_url( 'admin.php?page=charitable-settings&tab=gateways&group=gateways_paypal_commerce' ),
1719 + __( 'Connect with PayPal', 'charitable' )
1720 + )
1721 + );
1722 + }
1723 +
1724 + return __( 'Online donations are temporarily unavailable. Please check back soon.', 'charitable' );
1725 + }
1726 +
1727 + /**
1228 1728 * Return the donor value fields.
1229 1729 *
1230 1730 * @since 1.0.0
1231 1731 *
@@ -1271,9 +1771,9 @@
1271 1771 * Returns true if required fields are missing.
1272 1772 *
1273 1773 * @since 1.0.0
1274 1774 *
1275 - * @param array $required_fields
1775 + * @param array $required_fields
1276 1776 * @return boolean
1277 1777 */
1278 1778 protected function is_missing_required_fields( $required_fields ) {
1279 1779 if ( is_user_logged_in() ) {
@@ -1280,13 +1780,15 @@
1280 1780 return false;
1281 1781 }
1282 1782
1283 1783 if ( is_null( $this->get_submitted_value( 'gateway' ) ) ) {
1784 + charitable_get_notices()->add_error(
1785 + sprintf(
1786 + '<p>%s</p>',
1787 + __( 'Your donation could not be processed. No payment gateway was selected.', 'charitable' )
1788 + )
1789 + );
1284 1790
1285 - charitable_get_notices()->add_error( sprintf( '<p>%s</p>',
1286 - __( 'Your donation could not be processed. No payment gateway was selected.', 'charitable' )
1287 - ) );
1288 -
1289 1791 return false;
1290 1792 }
1291 1793
1292 1794 return ! $this->check_required_fields( $required_fields );
@@ -1297,9 +1799,9 @@
1297 1799 *
1298 1800 * @since 1.0.0
1299 1801 * @since 1.5.0 Deprecated. This is handled by `Charitable_Public_Form_View` now.
1300 1802 *
1301 - * @param string|false $custom_template
1803 + * @param string|false $custom_template Custom template.
1302 1804 * @return string|false|Charitable_Template
1303 1805 */
1304 1806 public function use_custom_templates( $custom_template ) {
1305 1807 charitable_get_deprecated()->deprecated_function(
@@ -1306,9 +1808,9 @@
1306 1808 __METHOD__,
1307 1809 '1.5.0'
1308 1810 );
1309 1811
1310 - return $custom_template;
1812 + return $custom_template;
1311 1813 }
1312 1814 }
1313 1815
1314 1816 endif;