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 +726 -52 1.6.8 → 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) 2019, 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,25 +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; ?>) {
675 +@media only screen and (max-width: <?php echo esc_attr( $breakpoint ); ?>) {
457 676 .campaign-loop.campaign-grid.masonry { -moz-column-count: 1; -webkit-column-count: 1; column-count: 1; }
458 - .campaign-loop.campaign-grid .campaign.hentry { width: 100% !important; }
677 + .campaign-loop.campaign-grid .campaign,.campaign-loop.campaign-grid .campaign.hentry { width: 100% !important; }
459 678 }
460 679 </style>
461 -<?php
680 + <?php
462 681 }
463 682
464 683 endif;
465 684
@@ -527,9 +746,9 @@
527 746 * @param mixed[] $args Optional arguments.
528 747 * @return void
529 748 */
530 749 function charitable_template_campaign_loop_more_link( $campaign, $args = array() ) {
531 - if ( ! isset( $args['button'] ) || 'details' != $args['button'] ) {
750 + if ( ! isset( $args['button'] ) || 'details' !== $args['button'] ) {
532 751 return;
533 752 }
534 753
535 754 charitable_template( 'campaign-loop/more-link.php', array( 'campaign' => $campaign ) );
@@ -568,8 +787,76 @@
568 787 }
569 788
570 789 endif;
571 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 +
572 859 // //////////////////////////////
573 860 // DONATION RECEIPT
574 861 // //////////////////////////////
575 862 if ( ! function_exists( 'charitable_template_donation_receipt_content' ) ) :
@@ -593,9 +880,8 @@
593 880 return $content;
594 881 }
595 882
596 883 return charitable_template_donation_receipt_output( $content );
597 -
598 884 }
599 885
600 886 endif;
601 887
@@ -622,18 +908,27 @@
622 908
623 909 ob_start();
624 910
625 911 if ( ! $donation->is_from_current_user() ) {
626 - 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 +
627 919 return ob_get_clean();
628 920 }
629 921
630 922 do_action( 'charitable_donation_receipt_page', $donation );
631 923
632 - charitable_template( 'content-donation-receipt.php', array(
633 - 'content' => $content,
634 - 'donation' => $donation,
635 - ) );
924 + charitable_template(
925 + 'content-donation-receipt.php',
926 + array(
927 + 'content' => $content,
928 + 'donation' => $donation,
929 + )
930 + );
636 931
637 932 $content = ob_get_clean();
638 933
639 934 return $content;
@@ -731,15 +1026,15 @@
731 1026
732 1027 /**
733 1028 * Display a prompt to login at the start of the user fields block.
734 1029 *
735 - * @since 1.0.0
1030 + * @since 1.0.0
1031 + * @version 1.8.2
736 1032 *
737 1033 * @param Charitable_Donation_Form_Interface $form The donation form object.
738 1034 * @return void
739 1035 */
740 1036 function charitable_template_donation_form_login( Charitable_Donation_Form_Interface $form ) {
741 -
742 1037 $user = $form->get_user();
743 1038
744 1039 if ( $user ) {
745 1040 return;
@@ -744,9 +1039,17 @@
744 1039 if ( $user ) {
745 1040 return;
746 1041 }
747 1042
748 - 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 + }
749 1052 }
750 1053
751 1054 endif;
752 1055
@@ -835,20 +1138,21 @@
835 1138 *
836 1139 * @since 1.4.14
837 1140 * @since 1.5.0 Third parameter has been changed from an instance of
838 1141 * `Charitable_Donation_Form` to a campaign ID.
1142 + * @since 1.8.3.6 Added <div> wrapper.
839 1143 *
840 1144 * @param string $amount_formatted The formatted amount.
841 1145 * @param int|float $amount The raw amount.
842 1146 * @param int $campaign_id Campaign ID.
843 1147 */
844 - $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 );
845 1149
846 - $content = '<p>';
1150 + $content = '<div class="charitable-your-donation-amount"><p>';
847 1151 /* translators: %s: donation amount */
848 1152 $content .= sprintf( __( 'Your Donation Amount: %s.', 'charitable' ), '<strong>' . $amount_formatted . '</strong>' );
849 1153 $content .= '&nbsp;<a href="#" class="change-donation" data-charitable-toggle="charitable-donation-options-' . esc_attr( $form_id ) . '">' . __( 'Change', 'charitable' ) . '</a>';
850 - $content .= '</p>';
1154 + $content .= '</div></p>';
851 1155
852 1156 return $content;
853 1157 }
854 1158
@@ -906,17 +1210,20 @@
906 1210 }
907 1211
908 1212 ob_start();
909 1213
910 - if ( isset( $_GET['email_sent'] ) ) {
1214 + if ( isset( $_GET['email_sent'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
911 1215
912 1216 charitable_template( 'account/forgot-password-sent.php' );
913 1217
914 1218 } else {
915 1219
916 - charitable_template( 'account/forgot-password.php', array(
917 - 'form' => new Charitable_Forgot_Password_Form(),
918 - ) );
1220 + charitable_template(
1221 + 'account/forgot-password.php',
1222 + array(
1223 + 'form' => new Charitable_Forgot_Password_Form(),
1224 + )
1225 + );
919 1226
920 1227 }
921 1228
922 1229 $content = ob_get_clean();
@@ -942,11 +1249,14 @@
942 1249 }
943 1250
944 1251 ob_start();
945 1252
946 - charitable_template( 'account/reset-password.php', array(
947 - 'form' => new Charitable_Reset_Password_Form(),
948 - ) );
1253 + charitable_template(
1254 + 'account/reset-password.php',
1255 + array(
1256 + 'form' => new Charitable_Reset_Password_Form(),
1257 + )
1258 + );
949 1259
950 1260 $content = ob_get_clean();
951 1261
952 1262 return $content;
@@ -959,8 +1269,9 @@
959 1269 /**
960 1270 * Display a link to the login form.
961 1271 *
962 1272 * @since 1.4.2
1273 + * @version 1.8.9.1
963 1274 *
964 1275 * @param Charitable_Registration_Form|null $form Instance of `Charitable_Registration_Form`, or
965 1276 * null in previous versions of Charitable.
966 1277 * @return void
@@ -977,13 +1288,148 @@
977 1288 if ( ! $form->get_login_link() ) {
978 1289 return;
979 1290 }
980 1291
981 - printf( '<p>%s</p>', $form->get_login_link() );
1292 + printf( '<p>%s</p>', wp_kses_post( $form->get_login_link() ) );
982 1293 }
983 1294
984 1295 endif;
985 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 +
986 1432 // //////////////////////////////
987 1433 // NOTICES
988 1434 // //////////////////////////////
989 1435 if ( ! function_exists( 'charitable_template_notices' ) ) :
@@ -1000,10 +1446,238 @@
1000 1446 if ( empty( $notices ) ) {
1001 1447 $notices = charitable_get_notices()->get_notices();
1002 1448 }
1003 1449
1004 - charitable_template_from_session( 'form-fields/notices.php', array(
1005 - 'notices' => $notices,
1006 - ), 'notices' );
1450 + charitable_template_from_session(
1451 + 'form-fields/notices.php',
1452 + array(
1453 + 'notices' => $notices,
1454 + ),
1455 + 'notices'
1456 + );
1007 1457 }
1008 1458
1009 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 +}