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 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 All 212 releases
← All changes | includes/public/charitable-template-functions.php +727 -52 1.6.6 → 1.8.13 View file →
@@ -4,13 +4,13 @@
4 4 *
5 5 * Functions used with template hooks.
6 6 *
7 7 * @package Charitable/Functions/Templates
8 - * @author Eric Daams
9 - * @copyright Copyright (c) 2018, Studio 164a
8 + * @author David Bisset
9 + * @copyright Copyright (c) 2023, WP Charitable LLC
10 10 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
11 11 * @since 1.0.0
12 - * @version 1.5.14
12 + * @version 1.8.9.1
13 13 */
14 14
15 15 // Exit if accessed directly.
16 16 if ( ! defined( 'ABSPATH' ) ) {
@@ -27,16 +27,22 @@
27 27 *
28 28 * This is used on the wp_head action.
29 29 *
30 30 * @since 1.2.0
31 + * @version 1.8.9.1
31 32 *
32 33 * @return void
33 34 */
34 35 function charitable_template_custom_styles() {
36 +
35 37 if ( ! apply_filters( 'charitable_add_custom_styles', true ) ) {
36 38 return;
37 39 }
38 40
41 + if ( defined( 'CHARITABLE_NO_CUSTOM_TEMPLATE_STYLES' ) && CHARITABLE_NO_CUSTOM_TEMPLATE_STYLES ) {
42 + return;
43 + }
44 +
39 45 $styles = get_transient( 'charitable_custom_styles' );
40 46
41 47 if ( false === $styles ) {
42 48
@@ -50,9 +56,9 @@
50 56
51 57 set_transient( 'charitable_custom_styles', $styles, 0 );
52 58 }
53 59
54 - echo $styles;
60 + echo $styles; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
55 61 }
56 62
57 63 endif;
58 64
@@ -124,17 +130,43 @@
124 130
125 131 /**
126 132 * Display the campaign description before the summary and rest of content.
127 133 *
128 - * @since 1.0.0
134 + * @since 1.0.0
135 + * @version 1.8.1 Add check for CHARITABLE_NO_LEGACY_CHECK_CAMPAIGN_DESCRIPTION constant.
136 + * @version 1.8.2 Added charitable_find_description_in_campaign_settings method
129 137 *
130 138 * @param Charitable_Campaign $campaign The campaign object.
139 + * @param array $view_args The view arguments.
131 140 * @return void
132 141 */
133 - function charitable_template_campaign_description( $campaign ) {
134 - charitable_template( 'campaign/description.php', array( 'campaign' => $campaign ) );
142 + function charitable_template_campaign_description( $campaign, $view_args = array() ) {
143 + if ( charitable_is_campaign_legacy( $campaign ) || ( defined( 'CHARITABLE_NO_LEGACY_CHECK_CAMPAIGN_DESCRIPTION' ) && CHARITABLE_NO_LEGACY_CHECK_CAMPAIGN_DESCRIPTION ) ) {
144 + charitable_template(
145 + 'campaign/description.php',
146 + array(
147 + 'campaign' => $campaign,
148 + 'view_args' => $view_args,
149 + )
150 + );
151 + } elseif ( $campaign->ID && ! empty( $view_args['shortcode'] ) ) {
152 + $campaign_settings = get_post_meta( $campaign->ID, 'campaign_settings_v2', true );
153 + if ( is_array( $campaign_settings ) && ! empty( $campaign_settings ) ) {
154 + $description_limit = isset( $view_args['description_limit'] ) ? intval( $view_args['description_limit'] ) : 0;
155 + $description = charitable_find_description_in_campaign_settings( $campaign_settings, $description_limit );
156 + charitable_template(
157 + 'campaign/description.php',
158 + array(
159 + 'campaign' => $campaign,
160 + 'description' => $description,
161 + 'view_args' => $view_args,
162 + )
163 + );
164 + }
165 + }
135 166 }
136 167
168 +
137 169 endif;
138 170
139 171 if ( ! function_exists( 'charitable_template_campaign_finished_notice' ) ) :
140 172
@@ -166,12 +198,22 @@
166 198 * @param Charitable_Campaign $campaign The campaign object.
167 199 * @return boolean True if the template was displayed. False otherwise.
168 200 */
169 201 function charitable_template_campaign_percentage_raised( $campaign ) {
202 + // Check if $campaign is a valid object.
203 + if ( ! is_a( $campaign, 'Charitable_Campaign' ) ) {
204 + return false;
205 + }
206 +
170 207 if ( ! $campaign->has_goal() ) {
171 208 return false;
172 209 }
173 210
211 + // Added in 1.7.0.9 - add filter for custom logic and now controllable by new tab for campaign settings.
212 + if ( false === apply_filters( 'charitable_display_template_campaign_percentage_raised', true, $campaign ) ) {
213 + return false;
214 + }
215 +
174 216 charitable_template( 'campaign/summary-percentage-raised.php', array( 'campaign' => $campaign ) );
175 217
176 218 return true;
177 219 }
@@ -205,8 +247,14 @@
205 247 * @param Charitable_Campaign $campaign The campaign object.
206 248 * @return true
207 249 */
208 250 function charitable_template_campaign_donor_count( $campaign ) {
251 +
252 + // Added in 1.7.0.9 - add filter for custom logic and now controllable by new tab for campaign settings.
253 + if ( false === apply_filters( 'charitable_display_template_campaign_donor_count', true, $campaign ) ) {
254 + return false;
255 + }
256 +
209 257 charitable_template( 'campaign/summary-donors.php', array( 'campaign' => $campaign ) );
210 258 return true;
211 259 }
212 260
@@ -222,12 +270,21 @@
222 270 * @param Charitable_Campaign $campaign The campaign object.
223 271 * @return boolean True if the template was displayed. False otherwise.
224 272 */
225 273 function charitable_template_campaign_time_left( $campaign ) {
274 + if ( ! is_a( $campaign, 'Charitable_Campaign' ) ) {
275 + return false;
276 + }
277 +
226 278 if ( $campaign->is_endless() ) {
227 279 return false;
228 280 }
229 281
282 + // Added in 1.7.0.9 - add filter for custom logic and now controllable by new tab for campaign settings.
283 + if ( false === apply_filters( 'charitable_display_template_campaign_time_remaining', true, $campaign ) ) {
284 + return false;
285 + }
286 +
230 287 charitable_template( 'campaign/summary-time-left.php', array( 'campaign' => $campaign ) );
231 288 return true;
232 289 }
233 290
@@ -243,8 +300,12 @@
243 300 * @param Charitable_Campaign $campaign The campaign object.
244 301 * @return boolean True if the template was displayed. False otherwise.
245 302 */
246 303 function charitable_template_donate_button( $campaign ) {
304 + if ( ! is_a( $campaign, 'Charitable_Campaign' ) ) {
305 + return false;
306 + }
307 +
247 308 if ( ! $campaign->can_receive_donations() ) {
248 309 return false;
249 310 }
250 311
@@ -265,9 +326,11 @@
265 326 * @param Charitable_Campaign $campaign The campaign object.
266 327 * @return void
267 328 */
268 329 function charitable_template_campaign_summary( $campaign ) {
269 - charitable_template( 'campaign/summary.php', array( 'campaign' => $campaign ) );
330 + if ( charitable_is_campaign_legacy( $campaign ) ) {
331 + charitable_template( 'campaign/summary.php', array( 'campaign' => $campaign ) );
332 + }
270 333 }
271 334
272 335 endif;
273 336
@@ -297,9 +360,11 @@
297 360 * @param Charitable_Campaign $campaign The campaign object.
298 361 * @return void
299 362 */
300 363 function charitable_template_campaign_donate_button( $campaign ) {
301 - charitable_template( 'campaign/donate-button.php', array( 'campaign' => $campaign ) );
364 + if ( charitable_is_campaign_legacy( $campaign ) ) {
365 + charitable_template( 'campaign/donate-button.php', array( 'campaign' => $campaign ) );
366 + }
302 367 }
303 368
304 369 endif;
305 370
@@ -342,13 +407,17 @@
342 407 *
343 408 * @since 1.0.0
344 409 * @since 1.5.0 Function now returns true/false depending
345 410 * on whether the template is rendered.
411 + * @since 1.8.1 Added check to see if charitable_get_current_donation_form() returns false, preventing fatal error
346 412 *
347 413 * @param Charitable_Campaign $campaign The campaign object.
348 414 * @return boolean
349 415 */
350 - function charitable_template_campaign_donation_form_in_page( Charitable_Campaign $campaign ) {
416 + function charitable_template_campaign_donation_form_in_page( $campaign ) {
417 + if ( ! is_a( $campaign, 'Charitable_Campaign' ) ) {
418 + return false;
419 + }
351 420 if ( $campaign->can_receive_donations() && 'same_page' == charitable_get_option( 'donation_form_display', 'separate_page' ) ) {
352 421 $donation_id = get_query_var( 'donation_id', false );
353 422
354 423 /* If a donation ID is included, make sure it belongs to the current user. */
@@ -355,9 +424,12 @@
355 424 if ( $donation_id && ! charitable_user_can_access_donation( $donation_id ) ) {
356 425 return false;
357 426 }
358 427
359 - charitable_get_current_donation_form()->render();
428 + if ( false !== charitable_get_current_donation_form() ) {
429 + charitable_get_current_donation_form()->render();
430 + }
431 +
360 432 return true;
361 433 }
362 434
363 435 return false;
@@ -372,35 +444,167 @@
372 444 *
373 445 * @since 1.0.0
374 446 * @since 1.5.0 Function now returns true/false depending
375 447 * on whether the template is rendered.
448 + * @version 1.8.2 Added additional pattern to search for campaign id in the content.
376 449 *
377 450 * @global WP_Query $wp_query
378 451 * @return boolean
379 452 */
380 453 function charitable_template_campaign_modal_donation_window() {
381 - global $wp_query;
454 + global $wp_query, $post;
382 455
383 - if ( Charitable::CAMPAIGN_POST_TYPE != get_post_type() ) {
456 + // We need to find the campaign so we can use charitable_get_current_campaign().
457 + if ( Charitable::CAMPAIGN_POST_TYPE === get_post_type() ) {
458 +
459 + if ( isset( $wp_query->query_vars['donate'] ) ) {
460 + return false;
461 + }
462 +
463 + $campaign_ids = array( charitable_get_current_campaign_id() );
464 +
465 + } elseif ( 'page' === get_post_type() && ! empty( $post->post_content ) ) {
466 +
467 + // Find all instances of {"campaignID":"126"} in the content and extract all the different campaign ID and put them into a PHP array.
468 + $pattern = '/{"campaignID":"(\d+)"}/';
469 + preg_match_all( $pattern, $post->post_content, $matches );
470 + $campaign_ids = array_unique( $matches[1] );
471 + // if empty, then find all instances of "campaign id=126" in the content and extract all the different campaign ID and put them into a PHP array.
472 + if ( empty( $campaign_ids ) ) {
473 + $pattern = '/campaign id="(\d+)"/';
474 + preg_match_all( $pattern, $post->post_content, $matches );
475 + $campaign_ids = array_unique( $matches[1] );
476 + }
477 +
478 + } else {
479 +
384 480 return false;
481 +
385 482 }
386 483
387 - if ( isset( $wp_query->query_vars['donate'] ) ) {
484 + if ( ! $campaign_ids ) {
388 485 return false;
389 486 }
390 487
391 - $campaign = charitable_get_current_campaign();
488 + foreach ( $campaign_ids as $campaign_id ) {
392 489
393 - if ( $campaign->can_receive_donations() && 'modal' == charitable_get_option( 'donation_form_display', 'separate_page' ) ) {
394 - charitable_template( 'campaign/donate-modal-window.php', array( 'campaign' => $campaign ) );
395 - return true;
490 + $campaign = charitable_get_campaign( $campaign_id );
491 +
492 + if ( $campaign->can_receive_donations() && 'modal' === charitable_get_option( 'donation_form_display', 'separate_page' ) ) {
493 + charitable_template( 'campaign/donate-modal-window.php', array( 'campaign' => $campaign ) );
494 + }
495 +
396 496 }
397 497
398 - return false;
498 + return true;
399 499 }
400 500
401 501 endif;
402 502
503 +if ( ! function_exists( 'charitable_template_elementor_campaign_modal_donation_window' ) ) :
504 +
505 + /**
506 + * Adds the modal donation window for Elementor widgets.
507 + *
508 + * @since 1.8.7.1
509 + *
510 + * @global WP_Post $post
511 + * @return boolean
512 + */
513 + function charitable_template_elementor_campaign_modal_donation_window() {
514 + global $post;
515 +
516 + // Only run if Elementor is active.
517 + if ( ! did_action( 'elementor/loaded' ) ) {
518 + return false;
519 + }
520 +
521 + // Only run on pages/posts.
522 + if ( ! $post || ! in_array( $post->post_type, array( 'page', 'post' ) ) ) {
523 + return false;
524 + }
525 +
526 + // Get Elementor data.
527 + $elementor_data = get_post_meta( $post->ID, '_elementor_data', true );
528 + if ( empty( $elementor_data ) ) {
529 + return false;
530 + }
531 +
532 + // Decode JSON data.
533 + $data = json_decode( $elementor_data, true );
534 + if ( ! is_array( $data ) ) {
535 + return false;
536 + }
537 +
538 + $campaign_ids = array();
539 +
540 + // Recursively search for Charitable widgets.
541 + $campaign_ids = charitable_extract_campaign_ids_from_elementor_data( $data );
542 +
543 + if ( empty( $campaign_ids ) ) {
544 + return false;
545 + }
546 +
547 + // Remove duplicates.
548 + $campaign_ids = array_unique( $campaign_ids );
549 +
550 + foreach ( $campaign_ids as $campaign_id ) {
551 +
552 + $campaign = charitable_get_campaign( $campaign_id );
553 +
554 + if ( $campaign->can_receive_donations() && 'modal' === charitable_get_option( 'donation_form_display', 'separate_page' ) ) {
555 + charitable_template( 'campaign/donate-modal-window.php', array( 'campaign' => $campaign ) );
556 + }
557 +
558 + }
559 +
560 + return true;
561 + }
562 +
563 +endif;
564 +
565 +if ( ! function_exists( 'charitable_extract_campaign_ids_from_elementor_data' ) ) :
566 +
567 + /**
568 + * Recursively extract campaign IDs from Elementor data.
569 + *
570 + * @since 1.8.7.1
571 + *
572 + * @param array $data Elementor data array.
573 + * @return array
574 + */
575 + function charitable_extract_campaign_ids_from_elementor_data( $data ) {
576 + $campaign_ids = array();
577 +
578 + foreach ( $data as $element ) {
579 + if ( ! is_array( $element ) ) {
580 + continue;
581 + }
582 +
583 + // Check if this is a Charitable widget.
584 + if ( isset( $element['widgetType'] ) ) {
585 + $widget_type = $element['widgetType'];
586 +
587 + // Check for Charitable campaign widgets.
588 + if ( in_array( $widget_type, array( 'charitable_campaign', 'charitable_button', 'charitable_donation_form' ) ) ) {
589 + if ( isset( $element['settings']['campaign_id'] ) && ! empty( $element['settings']['campaign_id'] ) ) {
590 + $campaign_ids[] = absint( $element['settings']['campaign_id'] );
591 + }
592 + }
593 + }
594 +
595 + // Recursively check child elements.
596 + if ( isset( $element['elements'] ) && is_array( $element['elements'] ) ) {
597 + $child_campaign_ids = charitable_extract_campaign_ids_from_elementor_data( $element['elements'] );
598 + $campaign_ids = array_merge( $campaign_ids, $child_campaign_ids );
599 + }
600 + }
601 +
602 + return $campaign_ids;
603 + }
604 +
605 +endif;
606 +
403 607 // //////////////////////////////
404 608 // CAMPAIGN LOOP
405 609 // //////////////////////////////
406 610 if ( ! function_exists( 'charitable_template_campaign_loop' ) ) :
@@ -421,12 +625,15 @@
421 625 global $wp_query;
422 626 $campaigns = $wp_query;
423 627 }
424 628
425 - charitable_template( 'campaign-loop.php', array(
426 - 'campaigns' => $campaigns,
427 - 'columns' => $columns,
428 - ) );
629 + charitable_template(
630 + 'campaign-loop.php',
631 + array(
632 + 'campaigns' => $campaigns,
633 + 'columns' => $columns,
634 + )
635 + );
429 636 }
430 637
431 638 endif;
432 639
@@ -435,8 +642,9 @@
435 642 /**
436 643 * Add responsive styles for the campaign loop.
437 644 *
438 645 * @since 1.4.0
646 + * @version 1.8.9.1
439 647 *
440 648 * @param WP_Query $campaigns The campaigns that will be displayed.
441 649 * @param array $args The view arguments.
442 650 * @return void
@@ -441,24 +649,36 @@
441 649 * @param array $args The view arguments.
442 650 * @return void
443 651 */
444 652 function charitable_template_responsive_styles( $campaigns, $args ) {
445 - if ( ! isset( $args['responsive'] ) || ! $args['responsive'] ) {
653 + if ( ! isset( $args['responsive'] ) || ! $args['responsive'] || is_admin() ) {
446 654 return;
447 655 }
448 656
657 + // Check if we're in Elementor editor or preview mode
658 + $is_elementor = false;
659 + if ( class_exists( '\Elementor\Plugin' ) ) {
660 + $is_elementor = \Elementor\Plugin::$instance->editor->is_edit_mode() || \Elementor\Plugin::$instance->preview->is_preview_mode();
661 + }
662 +
663 + // If we're in Elementor, don't output inline styles
664 + if ( $is_elementor ) {
665 + return;
666 + }
667 +
449 668 $breakpoint = '768px';
450 669
451 670 if ( preg_match( '/[px|em]/', $args['responsive'] ) ) {
452 671 $breakpoint = $args['responsive'];
453 672 }
454 -?>
673 + ?>
455 674 <style type="text/css" media="screen">
456 -@media only screen and (max-width: <?php echo $breakpoint; ?>) {
457 - .campaign-loop.campaign-grid .campaign.hentry { width: 100% !important; }
675 +@media only screen and (max-width: <?php echo esc_attr( $breakpoint ); ?>) {
676 + .campaign-loop.campaign-grid.masonry { -moz-column-count: 1; -webkit-column-count: 1; column-count: 1; }
677 + .campaign-loop.campaign-grid .campaign,.campaign-loop.campaign-grid .campaign.hentry { width: 100% !important; }
458 678 }
459 679 </style>
460 -<?php
680 + <?php
461 681 }
462 682
463 683 endif;
464 684
@@ -526,9 +746,9 @@
526 746 * @param mixed[] $args Optional arguments.
527 747 * @return void
528 748 */
529 749 function charitable_template_campaign_loop_more_link( $campaign, $args = array() ) {
530 - if ( ! isset( $args['button'] ) || 'details' != $args['button'] ) {
750 + if ( ! isset( $args['button'] ) || 'details' !== $args['button'] ) {
531 751 return;
532 752 }
533 753
534 754 charitable_template( 'campaign-loop/more-link.php', array( 'campaign' => $campaign ) );
@@ -567,8 +787,76 @@
567 787 }
568 788
569 789 endif;
570 790
791 +/* DONATION FORM */
792 +
793 +
794 +if ( ! function_exists( 'charitable_template_donation_form' ) ) :
795 +
796 + /**
797 + * Display a campaign's donation form.
798 + *
799 + * @since 1.6.55
800 + * @since 1.8.3.5 Added get_form_template().
801 + *
802 + * @param int $campaign_id The campaign ID.
803 + * @param array $args Args to pass to the view.
804 + * @return false|void
805 + */
806 + function charitable_template_donation_form( $campaign_id, $args = array() ) {
807 + if ( Charitable::CAMPAIGN_POST_TYPE !== get_post_type( $campaign_id ) ) {
808 + return false;
809 + }
810 +
811 + if ( ! array_key_exists( 'campaign_id', $args ) ) {
812 + $args['campaign_id'] = $campaign_id;
813 + }
814 +
815 + if ( ! charitable_campaign_can_receive_donations( $args['campaign_id'] ) ) {
816 + return false;
817 + }
818 +
819 + $donation_id = get_query_var( 'donation_id', false );
820 +
821 + /* If a donation ID is included, make sure it belongs to the current user. */
822 + if ( $donation_id && ! charitable_user_can_access_donation( $donation_id ) ) {
823 + return false;
824 + }
825 +
826 + if ( ! wp_script_is( 'charitable-script', 'enqueued' ) ) {
827 + Charitable_Public::get_instance()->enqueue_donation_form_scripts();
828 + }
829 +
830 + $form = charitable_get_campaign( $campaign_id )->get_donation_form();
831 +
832 + /**
833 + * Do something before rendering the donation form.
834 + *
835 + * @since 1.0.0
836 + *
837 + * @param Charitable_Donation_Form $form The donation form instance.
838 + */
839 + do_action( 'charitable_donation_form_before', $form );
840 +
841 + $args['form'] = $form;
842 + $args['form_template'] = $form->get_form_template();
843 + $args['campaign'] = $form->get_campaign();
844 +
845 + charitable_template( 'donation-form/form-donation.php', $args );
846 +
847 + /**
848 + * Do something after rendering the donation form.
849 + *
850 + * @since 1.0.0
851 + *
852 + * @param Charitable_Donation_Form $form The donation form instance.
853 + */
854 + do_action( 'charitable_donation_form_after', $form );
855 + }
856 +
857 +endif;
858 +
571 859 // //////////////////////////////
572 860 // DONATION RECEIPT
573 861 // //////////////////////////////
574 862 if ( ! function_exists( 'charitable_template_donation_receipt_content' ) ) :
@@ -592,9 +880,8 @@
592 880 return $content;
593 881 }
594 882
595 883 return charitable_template_donation_receipt_output( $content );
596 -
597 884 }
598 885
599 886 endif;
600 887
@@ -621,18 +908,27 @@
621 908
622 909 ob_start();
623 910
624 911 if ( ! $donation->is_from_current_user() ) {
625 - charitable_template_from_session( 'donation-receipt/not-authorized.php', array( 'content' => $content ), 'donation_receipt', array( 'donation_id' => $donation->ID ) );
912 + charitable_template_from_session(
913 + 'donation-receipt/not-authorized.php',
914 + array( 'content' => $content ),
915 + 'donation_receipt',
916 + array( 'donation_id' => $donation->ID )
917 + );
918 +
626 919 return ob_get_clean();
627 920 }
628 921
629 922 do_action( 'charitable_donation_receipt_page', $donation );
630 923
631 - charitable_template( 'content-donation-receipt.php', array(
632 - 'content' => $content,
633 - 'donation' => $donation,
634 - ) );
924 + charitable_template(
925 + 'content-donation-receipt.php',
926 + array(
927 + 'content' => $content,
928 + 'donation' => $donation,
929 + )
930 + );
635 931
636 932 $content = ob_get_clean();
637 933
638 934 return $content;
@@ -730,15 +1026,15 @@
730 1026
731 1027 /**
732 1028 * Display a prompt to login at the start of the user fields block.
733 1029 *
734 - * @since 1.0.0
1030 + * @since 1.0.0
1031 + * @version 1.8.2
735 1032 *
736 1033 * @param Charitable_Donation_Form_Interface $form The donation form object.
737 1034 * @return void
738 1035 */
739 1036 function charitable_template_donation_form_login( Charitable_Donation_Form_Interface $form ) {
740 -
741 1037 $user = $form->get_user();
742 1038
743 1039 if ( $user ) {
744 1040 return;
@@ -743,9 +1039,17 @@
743 1039 if ( $user ) {
744 1040 return;
745 1041 }
746 1042
747 - charitable_template( 'donation-form/donor-fields/login-form.php' );
1043 + $allow_login_form = apply_filters( 'charitable_donation_form_login_allow', true );
1044 +
1045 + if ( ! $allow_login_form ) {
1046 + return;
1047 + }
1048 +
1049 + if ( '0' !== charitable_get_option( 'donation_form_show_login_message', '1' ) ) {
1050 + charitable_template( 'donation-form/donor-fields/login-form.php' );
1051 + }
748 1052 }
749 1053
750 1054 endif;
751 1055
@@ -834,20 +1138,21 @@
834 1138 *
835 1139 * @since 1.4.14
836 1140 * @since 1.5.0 Third parameter has been changed from an instance of
837 1141 * `Charitable_Donation_Form` to a campaign ID.
1142 + * @since 1.8.3.6 Added <div> wrapper.
838 1143 *
839 1144 * @param string $amount_formatted The formatted amount.
840 1145 * @param int|float $amount The raw amount.
841 1146 * @param int $campaign_id Campaign ID.
842 1147 */
843 - $amount_formatted = apply_filters( 'charitable_session_donation_amount_formatted', charitable_format_money( $amount ), $amount, $campaign_id );
1148 + $amount_formatted = apply_filters( 'charitable_session_donation_amount_formatted', charitable_format_money( $amount, false, true ), $amount, $campaign_id );
844 1149
845 - $content = '<p>';
1150 + $content = '<div class="charitable-your-donation-amount"><p>';
846 1151 /* translators: %s: donation amount */
847 1152 $content .= sprintf( __( 'Your Donation Amount: %s.', 'charitable' ), '<strong>' . $amount_formatted . '</strong>' );
848 1153 $content .= '&nbsp;<a href="#" class="change-donation" data-charitable-toggle="charitable-donation-options-' . esc_attr( $form_id ) . '">' . __( 'Change', 'charitable' ) . '</a>';
849 - $content .= '</p>';
1154 + $content .= '</div></p>';
850 1155
851 1156 return $content;
852 1157 }
853 1158
@@ -905,17 +1210,20 @@
905 1210 }
906 1211
907 1212 ob_start();
908 1213
909 - if ( isset( $_GET['email_sent'] ) ) {
1214 + if ( isset( $_GET['email_sent'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
910 1215
911 1216 charitable_template( 'account/forgot-password-sent.php' );
912 1217
913 1218 } else {
914 1219
915 - charitable_template( 'account/forgot-password.php', array(
916 - 'form' => new Charitable_Forgot_Password_Form(),
917 - ) );
1220 + charitable_template(
1221 + 'account/forgot-password.php',
1222 + array(
1223 + 'form' => new Charitable_Forgot_Password_Form(),
1224 + )
1225 + );
918 1226
919 1227 }
920 1228
921 1229 $content = ob_get_clean();
@@ -941,11 +1249,14 @@
941 1249 }
942 1250
943 1251 ob_start();
944 1252
945 - charitable_template( 'account/reset-password.php', array(
946 - 'form' => new Charitable_Reset_Password_Form(),
947 - ) );
1253 + charitable_template(
1254 + 'account/reset-password.php',
1255 + array(
1256 + 'form' => new Charitable_Reset_Password_Form(),
1257 + )
1258 + );
948 1259
949 1260 $content = ob_get_clean();
950 1261
951 1262 return $content;
@@ -958,8 +1269,9 @@
958 1269 /**
959 1270 * Display a link to the login form.
960 1271 *
961 1272 * @since 1.4.2
1273 + * @version 1.8.9.1
962 1274 *
963 1275 * @param Charitable_Registration_Form|null $form Instance of `Charitable_Registration_Form`, or
964 1276 * null in previous versions of Charitable.
965 1277 * @return void
@@ -976,13 +1288,148 @@
976 1288 if ( ! $form->get_login_link() ) {
977 1289 return;
978 1290 }
979 1291
980 - printf( '<p>%s</p>', $form->get_login_link() );
1292 + printf( '<p>%s</p>', wp_kses_post( $form->get_login_link() ) );
981 1293 }
982 1294
983 1295 endif;
984 1296
1297 +if ( ! function_exists( 'charitable_maybe_hide_campaign_percentage_raised' ) ) :
1298 +
1299 + /**
1300 + * Determine if a campaign setting says to hide this. Return true to show, false to hide.
1301 + *
1302 + * @since 1.7.0.8
1303 + *
1304 + * @param boolean $current_value Current value of boolean passed in.
1305 + * @param Charitable_Campaign $campaign The campaign object.
1306 + * @return boolean
1307 + */
1308 + function charitable_maybe_hide_campaign_percentage_raised( $current_value = true, $campaign = false ) {
1309 +
1310 + if ( false === $campaign || 0 === $campaign->get_campaign_id() ) {
1311 + return $current_value;
1312 + }
1313 +
1314 + $campaign_hide_percent_raised = get_post_meta( $campaign->get_campaign_id(), '_campaign_hide_percent_raised', true );
1315 +
1316 + if ( false === $campaign_hide_percent_raised || empty( $campaign_hide_percent_raised ) ) {
1317 + return $current_value;
1318 + }
1319 +
1320 + if ( in_array( 'hide_percent_raised', $campaign_hide_percent_raised ) ) {
1321 + return false; // hide.
1322 + }
1323 +
1324 + return $current_value;
1325 + }
1326 +
1327 +endif;
1328 +
1329 +
1330 +if ( ! function_exists( 'charitable_maybe_hide_campaign_donor_count' ) ) :
1331 +
1332 + /**
1333 + * Determine if a campaign setting says to hide this. Return true to show, false to hide.
1334 + *
1335 + * @since 1.7.0.8
1336 + *
1337 + * @param boolean $current_value Current value of boolean passed in.
1338 + * @param Charitable_Campaign $campaign The campaign object.
1339 + *
1340 + * @return boolean
1341 + */
1342 + function charitable_maybe_hide_campaign_donor_count( $current_value = true, $campaign = false ) {
1343 +
1344 + if ( false === $campaign || 0 === $campaign->get_campaign_id() ) {
1345 + return $current_value;
1346 + }
1347 +
1348 + $campaign_hide_donor_count = get_post_meta( $campaign->get_campaign_id(), '_campaign_hide_number_of_donors', true );
1349 +
1350 + if ( false === $campaign_hide_donor_count || empty( $campaign_hide_donor_count ) ) {
1351 + return $current_value;
1352 + }
1353 +
1354 + if ( in_array( 'hide_number_of_donors', $campaign_hide_donor_count ) ) {
1355 + return false; // hide.
1356 + }
1357 +
1358 + return $current_value;
1359 + }
1360 +
1361 +endif;
1362 +
1363 +
1364 +if ( ! function_exists( 'charitable_maybe_hide_campaign_amount_donated' ) ) :
1365 +
1366 + /**
1367 + * Determine if a campaign setting says to hide this. Return true to show, false to hide.
1368 + *
1369 + * @since 1.7.0.8
1370 + *
1371 + * @param boolean $current_value Current value of boolean passed in.
1372 + * @param Charitable_Campaign $campaign The campaign object.
1373 + * @param int $amount The amount donated.
1374 + * @param int $goal The campaign goal.
1375 + * @return boolean
1376 + */
1377 + function charitable_maybe_hide_campaign_amount_donated( $current_value, $campaign, $amount, $goal ) { // phpcs:ignore
1378 +
1379 + if ( false === $campaign || 0 === $campaign->get_campaign_id() ) {
1380 + return $current_value;
1381 + }
1382 +
1383 + $campaign_hide_amount_donated = get_post_meta( $campaign->get_campaign_id(), '_campaign_hide_amount_donated', true );
1384 +
1385 + if ( false === $campaign_hide_amount_donated || empty( $campaign_hide_amount_donated ) ) {
1386 + return $current_value;
1387 + }
1388 +
1389 + if ( in_array( 'hide_amount_donated', $campaign_hide_amount_donated ) ) {
1390 + return false; // hide.
1391 + }
1392 +
1393 + return $current_value;
1394 + }
1395 +
1396 +endif;
1397 +
1398 +
1399 +if ( ! function_exists( 'charitable_maybe_hide_campaign_time_remaining' ) ) :
1400 +
1401 + /**
1402 + * Determine if a campaign setting says to hide this. Return true to show, false to hide.
1403 + *
1404 + * @since 1.7.0.8
1405 + *
1406 + * @param boolean $current_value Current value of boolean passed in.
1407 + * @return boolean
1408 + */
1409 + function charitable_maybe_hide_campaign_time_remaining( $current_value = true, $campaign = false ) {
1410 +
1411 + if ( false === $campaign || 0 === $campaign->get_campaign_id() ) {
1412 + return $current_value;
1413 + }
1414 +
1415 + $campaign_hide_time_remaining = get_post_meta( $campaign->get_campaign_id(), '_campaign_hide_time_remaining', true );
1416 +
1417 + if ( false === $campaign_hide_time_remaining || empty( $campaign_hide_time_remaining ) ) {
1418 + return $current_value;
1419 + }
1420 +
1421 + if ( in_array( 'hide_time_remaining', $campaign_hide_time_remaining ) ) {
1422 + return false; // hide.
1423 + }
1424 +
1425 + return $current_value;
1426 + }
1427 +
1428 +endif;
1429 +
1430 +
1431 +
985 1432 // //////////////////////////////
986 1433 // NOTICES
987 1434 // //////////////////////////////
988 1435 if ( ! function_exists( 'charitable_template_notices' ) ) :
@@ -999,10 +1446,238 @@
999 1446 if ( empty( $notices ) ) {
1000 1447 $notices = charitable_get_notices()->get_notices();
1001 1448 }
1002 1449
1003 - charitable_template_from_session( 'form-fields/notices.php', array(
1004 - 'notices' => $notices,
1005 - ), 'notices' );
1450 + charitable_template_from_session(
1451 + 'form-fields/notices.php',
1452 + array(
1453 + 'notices' => $notices,
1454 + ),
1455 + 'notices'
1456 + );
1006 1457 }
1007 1458
1008 1459 endif;
1460 +
1461 +if ( ! function_exists( 'charitable_is_campaign_legacy' ) ) :
1462 +
1463 + /**
1464 + * Determine if a campaign is using the legacy settings.
1465 + *
1466 + * @since 1.8.0
1467 + *
1468 + * @param mixed $campaign The campaign to check. Can be a campaign ID, a campaign object, or an array with an 'id' key.
1469 + * @return bool True if the campaign is using the legacy settings, false otherwise.
1470 + */
1471 + function charitable_is_campaign_legacy( $campaign = false ) {
1472 +
1473 + if ( ! $campaign ) {
1474 + return true;
1475 + }
1476 +
1477 + if ( is_array( $campaign ) && ! empty( $campaign['id'] ) ) {
1478 + $campaign_id = intval( $campaign['id'] );
1479 + } elseif ( is_int( $campaign ) ) { // a campaign ID.
1480 + $campaign_id = intval( $campaign );
1481 + } elseif ( is_a( $campaign, 'Charitable_Campaign' ) ) {
1482 + $campaign_id = $campaign->__get( 'ID' );
1483 + } else {
1484 + return true;
1485 + }
1486 +
1487 + $campaign_v2_settings = get_post_meta( $campaign_id, 'campaign_settings_v2', true );
1488 +
1489 + return ! empty( $campaign_v2_settings ) ? false : true;
1490 + }
1491 +
1492 +endif;
1493 +
1494 +/**
1495 + * Filters the allowed HTML tags for campaign builder fields.
1496 + *
1497 + * @since 1.8.0
1498 + *
1499 + * @param string|bool $text The text to filter.
1500 + *
1501 + * @return string|bool The filtered text.
1502 + */
1503 +function charitable_campaign_builder_filter_allowed_html( $text = false ) {
1504 +
1505 + $allowed_html_tags = apply_filters(
1506 + 'charitable_campaign_builder_html_allowed_tags',
1507 + array(
1508 + 'a' => [
1509 + 'href' => [],
1510 + 'class' => [],
1511 + 'target' => [],
1512 + ],
1513 + 'p' => [
1514 + 'class' => [],
1515 + ],
1516 + 'span' => [
1517 + 'class' => [],
1518 + ],
1519 + 'div' => [
1520 + 'class' => [],
1521 + ],
1522 + 'strong' => [
1523 + 'class' => [],
1524 + ],
1525 + 'em' => [
1526 + 'class' => [],
1527 + ],
1528 + 'b' => [
1529 + 'class' => [],
1530 + ],
1531 + 'i' => [
1532 + 'class' => [],
1533 + ],
1534 + 'h1' => [
1535 + 'class' => [],
1536 + ],
1537 + 'h2' => [
1538 + 'class' => [],
1539 + ],
1540 + 'h3' => [
1541 + 'class' => [],
1542 + ],
1543 + 'h4' => [
1544 + 'class' => [],
1545 + ],
1546 + 'h5' => [
1547 + 'class' => [],
1548 + ],
1549 + 'h6' => [
1550 + 'class' => [],
1551 + ],
1552 + )
1553 + );
1554 +
1555 + return wp_kses( $text, $allowed_html_tags );
1556 +}
1557 +
1558 +/**
1559 + * Returns the preview content for a given builder tab type.
1560 + *
1561 + * @since 1.8.0
1562 + *
1563 + * @param string $type The type of builder tab.
1564 + *
1565 + * @return string The preview content.
1566 + */
1567 +function charitable_builder_tab_content_preview_by_type( $type = 'html' ) {
1568 +
1569 + switch ( $type ) {
1570 +
1571 + case 'discussion':
1572 + $output = '
1573 + <div class="placeholder-row">
1574 + <div class="placeholder-column avatar big">
1575 + <span class="placeholder avatar big"></span>
1576 + </div>
1577 + <div class="placeholder-column">
1578 + <span class="placeholder"></span>
1579 + <span class="placeholder"></span>
1580 + <span class="placeholder"></span>
1581 + </div>
1582 + </div>
1583 + <div class="placeholder-row">
1584 + <div class="placeholder-column avatar big right">
1585 + <span class="placeholder avatar"></span>
1586 + </div>
1587 + <div class="placeholder-column">
1588 + <span class="placeholder"></span>
1589 + <span class="placeholder"></span>
1590 + <span class="placeholder"></span>
1591 + </div>
1592 + </div>
1593 + <div class="placeholder-row">
1594 + <div class="placeholder-column avatar big">
1595 + <span class="placeholder avatar big"></span>
1596 + </div>
1597 + <div class="placeholder-column">
1598 + <span class="placeholder"></span>
1599 + <span class="placeholder"></span>
1600 + <span class="placeholder"></span>
1601 + </div>
1602 + </div>
1603 + <div class="placeholder-row">
1604 + <div class="placeholder-column avatar big right">
1605 + <span class="placeholder avatar"></span>
1606 + </div>
1607 + <div class="placeholder-column">
1608 + <span class="placeholder"></span>
1609 + <span class="placeholder"></span>
1610 + <span class="placeholder"></span>
1611 + </div>
1612 + </div>
1613 + ';
1614 + break;
1615 +
1616 + case 'updates':
1617 + $output = '
1618 + <div class="placeholder-row">
1619 + <div class="placeholder-column avatar">
1620 + <span class="placeholder avatar"></span>
1621 + </div>
1622 + <div class="placeholder-column">
1623 + <span class="placeholder"></span>
1624 + <span class="placeholder"></span>
1625 + <span class="placeholder"></span>
1626 + </div>
1627 + </div>
1628 + <div class="placeholder-row">
1629 + <div class="placeholder-column avatar">
1630 + <span class="placeholder avatar"></span>
1631 + </div>
1632 + <div class="placeholder-column">
1633 + <span class="placeholder"></span>
1634 + <span class="placeholder"></span>
1635 + <span class="placeholder"></span>
1636 + </div>
1637 + </div>
1638 + <div class="placeholder-row">
1639 + <div class="placeholder-column avatar">
1640 + <span class="placeholder avatar"></span>
1641 + </div>
1642 + <div class="placeholder-column">
1643 + <span class="placeholder"></span>
1644 + <span class="placeholder"></span>
1645 + <span class="placeholder"></span>
1646 + </div>
1647 + </div>
1648 + <div class="placeholder-row">
1649 + <div class="placeholder-column avatar">
1650 + <span class="placeholder avatar"></span>
1651 + </div>
1652 + <div class="placeholder-column">
1653 + <span class="placeholder"></span>
1654 + <span class="placeholder"></span>
1655 + <span class="placeholder"></span>
1656 + </div>
1657 + </div>
1658 + <div class="placeholder-row">
1659 + <div class="placeholder-column avatar">
1660 + <span class="placeholder avatar"></span>
1661 + </div>
1662 + <div class="placeholder-column">
1663 + <span class="placeholder"></span>
1664 + <span class="placeholder"></span>
1665 + <span class="placeholder"></span>
1666 + </div>
1667 + </div>
1668 + ';
1669 + break;
1670 +
1671 + default:
1672 + $output = '';
1673 + // $output = '
1674 +
1675 + // <div>
1676 + // <span class="placeholder big"></span>
1677 + // </div>
1678 + // ';
1679 + break;
1680 + }
1681 +
1682 + return $output;
1683 +}