PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.12
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.12
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
charitable / includes / campaigns / class-charitable-campaign.php

class-charitable-campaign.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.12, at includes/campaigns/class-charitable-campaign.php

1,628 lines 43.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Campaign model.
4 *
5 * @package Charitable/Classes/Charitable_Campaign
6 * @author David Bisset
7 * @copyright Copyright (c) 2023, WP Charitable LLC
8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 * @since 1.0.0
10 * @version 1.6.54
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Campaign' ) ) :
19
20 /**
21 * Campaign Model
22 *
23 * @since 1.0.0
24 *
25 * @property int $ID
26 * @property int $post_author
27 * @property string $post_date
28 * @property string $post_date_gmt
29 * @property string $post_content
30 * @property string $post_title
31 * @property string $post_excerpt
32 * @property string $post_status
33 * @property string $comment_status
34 * @property string $ping_status
35 * @property string $post_password
36 * @property string $post_name
37 * @property string $to_ping
38 * @property string $pinged
39 * @property string $post_modified
40 * @property string $post_modified_gmt
41 * @property string $post_content_filtered
42 * @property int $post_parent
43 * @property string $guid
44 * @property int $menu_order
45 * @property string $post_type
46 * @property string $post_mime_type
47 * @property int $comment_count
48 * @property string $filter
49 */
50 class Charitable_Campaign {
51
52 /**
53 * The WP_Post object associated with this campaign.
54 *
55 * @var WP_Post
56 */
57 private $post;
58
59 /**
60 * The timestamp for the expiry for this campaign.
61 *
62 * @var int
63 */
64 private $end_time;
65
66 /**
67 * The fundraising goal for the campaign.
68 *
69 * @var string|false
70 */
71 private $goal;
72
73 /**
74 * The fundraising goal for the campaign.
75 *
76 * @var string|false
77 */
78 private $min_donation_amount;
79
80 /**
81 * The donations made to this campaign.
82 *
83 * @var WP_Query|false
84 */
85 private $donations;
86
87 /**
88 * The amount donated to the campaign.
89 *
90 * @var int|false
91 */
92 private $donated_amount;
93
94 /**
95 * The form object for this campaign.
96 *
97 * @var Charitable_Donation_Form
98 */
99 private $donation_form;
100
101 /**
102 * The Charitable_Object_Fields object for this campaign.
103 *
104 * @since 1.6.0
105 *
106 * @var Charitable_Object_Fields
107 */
108 protected $fields;
109
110 /**
111 * Class constructor.
112 *
113 * @since 1.0.0
114 *
115 * @param mixed $post The post ID or WP_Post object for this this campaign.
116 */
117 public function __construct( $post ) {
118 if ( ! $post instanceof WP_Post ) {
119 $post = get_post( $post );
120 }
121
122 add_filter( 'charitable_campaign_description_template_content', array( $this, 'description_content' ), 10, 2 );
123
124 $this->post = $post;
125 }
126
127 /**
128 * Return description content.
129 *
130 * @since 1.7.0.4
131 *
132 * @param string $content The content.
133 * @param object $campaign The campaign object.
134 * @return mixed
135 */
136 public function description_content( $content = false, $campaign = false ) {
137
138 // search for YouTube and Vimeo video urls by default and attempt to convert them to oembed.
139
140 preg_match_all( '#(?<=v=|v\/|vi=|vi\/|youtu.be\/)[a-zA-Z0-9_-]{11}#', $content, $matches );
141
142 if ( $matches ) :
143 foreach ( $matches as $video_id ) {
144 if ( ! empty( $video_id ) ) :
145 $video_embed_args = apply_filters( 'charitable_campaign_description_template_video', array(), 'youtube', $video_id, $content );
146 $embed = wp_oembed_get( 'https://youtube.com/watch?v=' . $video_id[0], $video_embed_args );
147
148 $content = str_replace( trim( 'https://youtube.com/watch?v=' . $video_id[0] ), $embed, $content );
149 $content = str_replace( trim( 'http://youtube.com/watch?v=' . $video_id[0] ), $embed, $content );
150 $content = str_replace( trim( 'https://www.youtube.com/watch?v=' . $video_id[0] ), $embed, $content );
151 $content = str_replace( trim( 'http://www.youtube.com/watch?v=' . $video_id[0] ), $embed, $content );
152 endif;
153 }
154 endif;
155
156 preg_match( '/https?:\/\/(?:www\.)?vimeo\.com\/\d{8}/', $content, $matches );
157
158 if ( $matches ) :
159 foreach ( $matches as $video_url ) {
160 if ( ! empty( $video_id ) ) :
161 $video_embed_args = apply_filters( 'charitable_campaign_description_template_video', array(), 'vimeo', $video_id, $content, $campaign );
162 $embed = wp_oembed_get( $video_url, $video_embed_args );
163
164 $content = str_replace( trim( $video_url ), $embed, $content );
165 endif;
166 }
167 endif;
168
169 // allow developers and plugins to hook into content.
170 $content = apply_filters( 'charitable_campaign_description_content', $content, $campaign );
171
172 // apply WP's the_content filter, which other plugins can hook into.
173 $content = apply_filters( 'the_content', $content ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- 'the_content' is a WordPress core filter hook.
174
175 return $content;
176 }
177
178 /**
179 * Magic getter.
180 *
181 * @since 1.0.0
182 *
183 * @param string $key The key of the field to get.
184 * @return mixed
185 */
186 public function __get( $key ) {
187 if ( null !== $this->post && property_exists( $this->post, $key ) ) {
188 return $this->post->$key;
189 }
190
191 return $this->get( $key );
192 }
193
194 /**
195 * Limit properties to be serialized.
196 *
197 * @since 1.6.18
198 *
199 * @return array
200 */
201 public function __sleep() {
202 return array(
203 'post',
204 'end_time',
205 'goal',
206 'donations',
207 'donated_amount',
208 'donation_form',
209 );
210 }
211
212 /**
213 * Returns the campaign's post_meta values. _campaign_ is automatically prepended to the meta key.
214 *
215 * @see get_post_meta
216 *
217 * @since 1.0.0
218 *
219 * @param string $key The field key.
220 * @param boolean $single Whether to return a single value or an array.
221 * @return mixed This will return an array if single is false. If it's true, the value of the
222 * meta_value field will be returned.
223 */
224 public function get( $key, $single = true ) {
225 if ( $this->fields()->has_value_callback( $key ) ) {
226 return $this->fields()->get( $key );
227 }
228
229 /* Look for a local method. */
230 if ( method_exists( $this, 'get_' . $key ) ) {
231 $method = 'get_' . $key;
232 return $this->$method();
233 }
234
235 return $this->get_meta( '_campaign_' . $key, $single );
236 }
237
238 /**
239 * Return the campaign's post_meta values.
240 *
241 * @since since
242 *
243 * @param string $meta_name The meta key.
244 * @param boolean $single Whether to return a single value or an array.
245 * @return mixed This will return an array if single is false. If it's true, the value of the
246 * meta_value field will be returned.
247 */
248 public function get_meta( $meta_name, $single = true ) {
249
250 if ( empty( $this->post->ID ) ) {
251 return;
252 }
253
254 /**
255 * Filter the meta value of a particular campaign field.
256 *
257 * @since 1.0.0
258 *
259 * @param mixed $value The meta value.
260 * @param string $meta_name The name of the meta field.
261 * @param boolean $single Whether we're returning a single result.
262 * @param Charitable_Campaign $campaign This instance of `Charitable_Campaign`.
263 */
264 return apply_filters( 'charitable_campaign_get_meta_value', get_post_meta( $this->post->ID, $meta_name, $single ), $meta_name, $single, $this );
265 }
266
267 /**
268 * Return the Charitable_Object_Fields instance.
269 *
270 * @since 1.6.0
271 *
272 * @return Charitable_Object_Fields
273 */
274 public function fields() {
275 if ( ! isset( $this->fields ) ) {
276 $this->fields = new Charitable_Object_Fields( charitable()->campaign_fields(), $this );
277 }
278
279 return $this->fields;
280 }
281
282 /**
283 * Returns the id of the campaign (post).
284 *
285 * @since 1.7.0.9
286 * @version 1.8.0
287 *
288 * @return integer
289 */
290 public function get_campaign_id() {
291 return ( isset( $this->post->ID ) ) ? intval( $this->post->ID ) : false;
292 }
293
294 /**
295 * Returns whether the campaign is endless (i.e. no end date has been set).
296 *
297 * @since 1.0.0
298 *
299 * @return boolean
300 */
301 public function is_endless() {
302 return 0 == $this->get_meta( '_campaign_end_date' );
303 }
304
305 /**
306 * Return whether the campaign supports custom donation amounts.
307 *
308 * @since 1.6.53
309 *
310 * @return boolean
311 */
312 public function get_allow_custom_donations() {
313 return (int) get_post_meta( $this->post->ID, '_campaign_allow_custom_donations', true );
314 }
315
316 /**
317 * Return the suggested amounts, or an empty array if there are none.
318 *
319 * @since 1.0.0
320 *
321 * @return array
322 */
323 public function get_suggested_donations() {
324 $value = get_post_meta( $this->post->ID, '_campaign_suggested_donations', true );
325
326 if ( ! is_array( $value ) ) {
327 $value = array();
328 }
329
330 return apply_filters( 'charitable_campaign_suggested_donations', $value, $this );
331 }
332
333 /**
334 * Return the suggested amounts, or an empty array if there are none.
335 *
336 * @since 1.0.0
337 *
338 * @return array
339 */
340 public function get_suggested_donations_default() {
341 $value = get_post_meta( $this->post->ID, '_campaign_suggested_donations_default', true );
342
343 if ( is_array( $value ) && isset( $value[0] ) ) {
344 $value = $value[0];
345 }
346
347 return apply_filters( 'charitable_campaign_suggested_donations_default', $value, $this );
348 }
349
350 /**
351 * Returns the end date in your preferred format.
352 *
353 * If a format is not provided, the user-defined date_format in WordPress settings is used.
354 *
355 * @since 1.0.0
356 *
357 * @param string $date_format A date format accepted by PHP's date() function.
358 * @return string|false String if an end date is set. False if campaign has no end date.
359 */
360 public function get_end_date( $date_format = '' ) {
361 if ( $this->is_endless() ) {
362 return false;
363 }
364
365 if ( ! strlen( $date_format ) ) {
366 $date_format = get_option( 'date_format', 'd/m/Y' );
367 }
368
369 /* Filter the end date format using the charitable_campaign_end_date_format hook. */
370 $date_format = apply_filters( 'charitable_campaign_end_date_format', $date_format, $this );
371
372 /* This is how the end date is stored in the database, so just return that directly. */
373 if ( 'Y-m-d H:i:s' == $date_format ) {
374 return $this->get_meta( '_campaign_end_date' );
375 }
376
377 return date_i18n( $date_format, $this->get_end_time() );
378 }
379
380 /**
381 * Returns the timetamp of the end date.
382 *
383 * @since 1.0.0
384 * @since 1.8.1.10
385 *
386 * @return int|false Int if campaign has an end date. False if campaign has no end date.
387 */
388 public function get_end_time() {
389 if ( ! isset( $this->end_time ) ) {
390 $end_date = $this->get_meta( '_campaign_end_date' );
391
392 if ( ! $end_date ) {
393 return false;
394 }
395
396 /* The date is stored in the format of Y-m-d H:i:s. */
397 $date_time = explode( ' ', $end_date );
398 $date = explode( '-', $date_time[0] );
399 $time = explode( ':', $date_time[1] );
400
401 // Check for undefined array keys. If any of these are not defined, return false.
402 if ( ! isset( $date[0] ) || ! isset( $date[1] ) || ! isset( $date[2] ) || ! isset( $time[0] ) || ! isset( $time[1] ) || ! isset( $time[2] ) ) {
403 return false;
404 }
405
406 $this->end_time = mktime( $time[0], $time[1], $time[2], $date[1], $date[2], $date[0] );
407 }
408
409 return $this->end_time;
410 }
411
412 /**
413 * Returns the amount of time left in the campaign in seconds.
414 *
415 * @since 1.0.0
416 *
417 * @return int $time_left Int if campaign has an end date. False if campaign has no end date.
418 */
419 public function get_seconds_left() {
420 if ( $this->is_endless() ) {
421 return false;
422 }
423
424 $time_left = $this->get_end_time() - current_time( 'timestamp' );
425
426 return $time_left < 0 ? 0 : $time_left;
427 }
428
429 /**
430 * Returns the amount of time left in the campaign as a descriptive string.
431 *
432 * @uses charitable_campaign_ended Change the text displayed when there is no time left.
433 * @uses charitabile_campaign_minutes_left Change the text displayed when there is less than an hour left.
434 * @uses charitabile_campaign_hours_left Change the text displayed when there is less than a day left.
435 * @uses charitabile_campaign_days_left Change the text displayed when there is more than a day left.
436 * @uses charitable_campaign_time_left Change the text displayed when there is time left.
437 *
438 * @since 1.0.0
439 *
440 * @return string
441 */
442 public function get_time_left() {
443 if ( $this->is_endless() ) {
444 return '';
445 }
446
447 $hour = 3600;
448 $day = 86400;
449
450 $seconds_left = $this->get_seconds_left();
451
452 if ( 0 === $seconds_left ) {
453
454 /* Condition 1: The campaign has finished. */
455
456 $time_left = apply_filters( 'charitable_campaign_ended', __( 'Campaign has ended', 'charitable' ), $this );
457
458 } elseif ( $seconds_left <= $hour ) {
459
460 /* Condition 2: There is less than an hour left. */
461
462 $minutes_remaining = ceil( $seconds_left / 60 );
463 $time_left = apply_filters(
464 'charitabile_campaign_minutes_left', // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- This is a legacy hook used by other Charitable code. Changing it would break existing functionality.
465 // translators: %s is the number of minutes left.
466 sprintf( _n( '%s Minute Left', '%s Minutes Left', $minutes_remaining, 'charitable' ), '<span class="amount time-left minutes-left">' . $minutes_remaining . '</span>' ),
467 $this
468 );
469
470 } elseif ( $seconds_left <= $day ) {
471
472 /* Condition 3: There is less than a day left. */
473
474 $hours_remaining = floor( $seconds_left / 3600 );
475 $time_left = apply_filters(
476 'charitabile_campaign_hours_left', // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- This is a legacy hook used by other Charitable code. Changing it would break existing functionality.
477 // translators: %s is the number of hours left.
478 sprintf( _n( '%s Hour Left', '%s Hours Left', $hours_remaining, 'charitable' ), '<span class="amount time-left hours-left">' . $hours_remaining . '</span>' ),
479 $this
480 );
481
482 } else {
483
484 /* Condition 4: There is more than a day left. */
485
486 $days_remaining = floor( $seconds_left / 86400 );
487 $time_left = apply_filters(
488 'charitabile_campaign_days_left', // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- This is a legacy hook used by other Charitable code. Changing it would break existing functionality.
489 // translators: %s is the number of days left.
490 sprintf( _n( '%s Day Left', '%s Days Left', $days_remaining, 'charitable' ), '<span class="amount time-left days-left">' . $days_remaining . '</span>' ),
491 $this
492 );
493
494 } //end if
495
496 return apply_filters( 'charitable_campaign_time_left', $time_left, $this );
497 }
498
499 /**
500 * Returns whether the campaign has ended.
501 *
502 * @since 1.0.0
503 *
504 * @return boolean
505 */
506 public function has_ended() {
507 return ! $this->is_endless() && 0 == $this->get_seconds_left();
508 }
509
510 /**
511 * Returns whether a campaign is currently able to receive donations.
512 *
513 * @since 1.5.0
514 *
515 * @return boolean
516 */
517 public function can_receive_donations() {
518 $can = 'active' == $this->get_status();
519
520 /**
521 * Filter whether the campaign can receive donations.
522 *
523 * @since 1.5.0
524 *
525 * @param boolean $can Whether the campaign can receive donations.
526 * @param Charitable_Campaign $campaign This instance of `Charitable_Campaign`.
527 */
528 return apply_filters( 'charitable_campaign_can_receive_donations', $can, $this );
529 }
530
531 /**
532 * Return a text notice to say that a campaign has finished.
533 *
534 * @since 1.0.0
535 *
536 * @return string
537 */
538 public function get_finished_notice() {
539 if ( ! $this->has_ended() ) {
540 return '';
541 }
542
543 if ( ! $this->has_goal() ) {
544 // translators: %s is the time since the campaign ended.
545 $message = __( 'This campaign ended %s ago', 'charitable' );
546 } elseif ( $this->has_achieved_goal() ) {
547 // translators: %s is the time since the campaign ended.
548 $message = __( 'This campaign successfully reached its funding goal and ended %s ago', 'charitable' );
549 } else {
550 // translators: %s is the time since the campaign ended.
551 $message = __( 'This campaign failed to reach its funding goal %s ago', 'charitable' );
552 }
553
554 return apply_filters( 'charitable_campaign_finished_notice', sprintf( $message, '<span class="time-ago">' . human_time_diff( $this->get_end_time() ) . '</span>' ), $this );
555 }
556
557 /**
558 * Return the time since the campaign finished, or zero if it's still going.
559 *
560 * @since 1.0.0
561 *
562 * @return int
563 */
564 public function get_time_since_ended() {
565 if ( 0 !== $this->get_seconds_left() ) {
566 return 0;
567 }
568
569 return current_time( 'U' ) - $this->get_end_time();
570 }
571
572 /**
573 * Returns the fundraising goal of the campaign.
574 *
575 * @since 1.0.0
576 *
577 * @return string|false Amount if goal is set. False otherwise.
578 */
579 public function get_goal() {
580 if ( ! isset( $this->goal ) ) {
581 $this->goal = $this->has_goal() ? $this->get_meta( '_campaign_goal' ) : false;
582 }
583
584 return $this->goal;
585 }
586
587 /**
588 * Returns the minimum donation amount of the campaign.
589 *
590 * @since 1.0.0
591 *
592 * @return string|false Amount if goal is set. False otherwise.
593 */
594 public function get_min_donation_amount() {
595 if ( ! isset( $this->min_donation_amount ) ) {
596 $this->min_donation_amount = $this->get_meta( '_campaign_min_donation_amount' ) ? $this->get_meta( '_campaign_min_donation_amount' ) : false;
597 }
598
599 return $this->min_donation_amount;
600 }
601
602
603 /**
604 * Returns whether a goal has been set (anything greater than $0 is a goal).
605 *
606 * @since 1.0.0
607 *
608 * @return boolean
609 */
610 public function has_goal() {
611 return 0 < (float) $this->get_meta( '_campaign_goal' );
612 }
613
614 /**
615 * Returns the fundraising goal formatted as a monetary amount.
616 *
617 * @since 1.0.0
618 *
619 * @return string
620 */
621 public function get_monetary_goal() {
622 if ( ! $this->has_goal() ) {
623 return '';
624 }
625
626 return charitable_format_money( (string) $this->get_meta( '_campaign_goal' ) );
627 }
628
629 /**
630 * Returns whether the goal has been achieved.
631 *
632 * @since 1.0.0
633 *
634 * @return boolean
635 */
636 public function has_achieved_goal() {
637 return $this->get_donated_amount( true ) >= $this->get_goal();
638 }
639
640 /**
641 * Return a message to say whether the campaign has achieved its goal.
642 *
643 * @since 1.6.0
644 *
645 * @param string $success Optional. The success message.
646 * @param string $failure Optional. The failure message.
647 * @return string
648 */
649 public function get_goal_achieved_message( $success = '', $failure = '' ) {
650 if ( $this->has_achieved_goal() ) {
651
652 if ( strlen( $success ) ) {
653 return $success;
654 }
655
656 /**
657 * Filter the default message to show when a campaign has achieved its goal.
658 *
659 * @since 1.6.0
660 *
661 * @param string $message The success message.
662 * @param Charitable_Campaign $campaign This instance of `Charitable_Campaign`.
663 */
664 return apply_filters( 'charitable_campaign_goal_achievement_success_message', __( 'The campaign achieved its fundraising goal.', 'charitable' ), $this );
665 }
666
667 if ( strlen( $failure ) ) {
668 return $failure;
669 }
670
671 /**
672 * Filter the default message to show when a campaign has not achieved its goal.
673 *
674 * @since 1.6.0
675 *
676 * @param string $message The failure message.
677 * @param Charitable_Campaign $campaign This instance of `Charitable_Campaign`.
678 */
679 return apply_filters( 'charitable_campaign_goal_achievement_failure_message', __( 'The campaign did not reach its fundraising goal.', 'charitable' ), $this );
680 }
681
682 /**
683 * Return the campaign status.
684 *
685 * If the campaign is published, this will return whether either 'active' or 'finished'.
686 *
687 * @since 1.0.0
688 *
689 * @return string
690 */
691 public function get_status() {
692
693 $status = $post_status = isset( $this->post ) && ! empty( $this->post->post_status ) ? $this->post->post_status : false; // phpcs:ignore
694
695 if ( 'publish' == $status ) {
696 $status = $this->has_ended() ? 'finished' : 'active';
697 }
698
699 /**
700 * Filter the returned campaign status.
701 *
702 * @since 1.0.0
703 *
704 * @param string $status The campaign status.
705 * @param string $post_status The post_status of the campaign.
706 * @param Charitable_Campaign $campaign This instance of `Charitable_Campaign`.
707 */
708 return apply_filters( 'charitable_campaign_status', $status, $post_status, $this );
709 }
710
711 /**
712 * Return a status key for the campaign.
713 *
714 * This will return one of the following:
715 *
716 * inactive : A campaign that is not published.
717 * ended : A campaign without a goal has finished
718 * successful : A campaign with a goal has finished & achieved its goal
719 * unsucessful : A campaign with a goal has finished without achieving its goal
720 * ending : A campaign is ending soon.
721 * active : A campaign that is active and not ending soon.
722 *
723 * @since 1.3.7
724 *
725 * @return string
726 */
727 public function get_status_key() {
728 /**
729 * Set the threshold in seconds for defining whether a campaign is ending soon.
730 *
731 * @since 1.0.0
732 *
733 * @param int $seconds By default, this equals 604,800.
734 */
735 $ending_soon_threshold = apply_filters( 'charitable_campaign_ending_soon_threshold', WEEK_IN_SECONDS );
736 $ended = $this->has_ended();
737
738 if ( 'publish' != $this->post->post_status ) {
739 return 'inactive';
740 }
741
742 if ( $ended && ! $this->has_goal() ) {
743 return 'ended';
744 }
745
746 if ( $ended && $this->has_achieved_goal() ) {
747 return 'successful';
748 }
749
750 if ( $ended ) {
751 return 'unsucessful';
752 }
753
754 if ( ! $this->is_endless() && $this->get_seconds_left() < $ending_soon_threshold ) {
755 return 'ending';
756 }
757
758 return 'active';
759 }
760
761 /**
762 * Return the campaign status tag.
763 *
764 * @since 1.0.0
765 *
766 * @param boolean $show_achievement Whether to show the achievement status tag.
767 * @param boolean $show_active_tag Whether to show the active status tag.
768 *
769 * @return string
770 */
771 public function get_status_tag( $show_achievement = null, $show_active_tag = null ) {
772 $key = $this->get_status_key();
773
774 if ( is_null( $show_achievement ) ) {
775 $show_achievement = apply_filters( 'charitable_campaign_show_achievement_status_tag', true );
776 }
777
778 if ( is_null( $show_active_tag ) ) {
779 $show_active_tag = apply_filters( 'charitable_campaign_show_active_status_tag', false );
780 }
781
782 switch ( $key ) {
783 case 'ended':
784 $tag = __( 'Ended', 'charitable' );
785 break;
786
787 case 'successful':
788 $tag = $show_achievement ? __( 'Successful', 'charitable' ) : __( 'Ended', 'charitable' );
789 break;
790
791 case 'unsucessful':
792 $tag = $show_achievement ? __( 'Unsuccessful', 'charitable' ) : __( 'Ended', 'charitable' );
793 break;
794
795 case 'ending':
796 $tag = __( 'Ending Soon', 'charitable' );
797 break;
798
799 case 'active':
800 case 'publish':
801 $tag = $show_active_tag ? __( 'Active', 'charitable' ) : '';
802 break;
803
804 case 'inactive':
805 switch ( $this->post->post_status ) {
806 case 'pending':
807 $tag = __( 'Pending', 'charitable' );
808 break;
809
810 case 'draft':
811 $tag = __( 'Draft', 'charitable' );
812 break;
813
814 case 'future':
815 $tag = __( 'Scheduled', 'charitable' );
816 break;
817
818 default:
819 $tag = '';
820 }
821 break;
822
823 default:
824 $tag = '';
825
826 }//end switch
827
828 /**
829 * Filter the campaign status tag.
830 *
831 * @since 1.0.0
832 *
833 * @param string $tag The tag for the status.
834 * @param string $key The key of the current status.
835 * @param Charitable_Campaign $this This campaign object.
836 */
837 return apply_filters( 'charitable_campaign_status_tag', $tag, $key, $this );
838 }
839
840 /**
841 * Return the permalink for this campaign.
842 *
843 * @since 1.6.0
844 *
845 * @return string|false The permalink URL or false if post does not exist.
846 */
847 public function get_permalink() {
848 return get_permalink( $this->ID );
849 }
850
851 /**
852 * Return the admin edit link for this campaign.
853 *
854 * @since 1.6.0
855 *
856 * @return string
857 */
858 public function get_admin_edit_link() {
859 $post_type_object = get_post_type_object( Charitable::CAMPAIGN_POST_TYPE );
860
861 if ( $post_type_object->_edit_link ) {
862 $link = admin_url( sprintf( $post_type_object->_edit_link . '&amp;action=edit', $this->ID ) );
863 } else {
864 $link = '';
865 }
866
867 return $link;
868 }
869
870 /**
871 * Returns the donations made to this campaign.
872 *
873 * @since 1.0.0
874 *
875 * @return WP_Query
876 */
877 public function get_donations() {
878 $this->donations = get_transient( self::get_donations_cache_key( $this->ID ) );
879
880 if ( false === $this->donations ) {
881
882 $this->donations = charitable_get_table( 'campaign_donations' )->get_donations_on_campaign( $this->ID );
883
884 set_transient( self::get_donations_cache_key( $this->ID ), $this->donations, 0 );
885 }
886
887 return $this->donations;
888 }
889
890 /**
891 * Return the current amount of donations.
892 *
893 * @since 1.0.0
894 *
895 * @param boolean $sanitize Whether to sanitize the amount. False by default.
896 * @return string String if $sanitize is false. If $sanitize is true, return a float or WP_Error if the amount is not a string.
897 */
898 public function get_donated_amount( $sanitize = false ) {
899 $this->donated_amount = get_transient( self::get_donation_amount_cache_key( $this->ID ) );
900
901 if ( false === $this->donated_amount ) {
902 $this->donated_amount = charitable_get_table( 'campaign_donations' )->get_campaign_donated_amount( $this->ID, false, false );
903
904 set_transient( self::get_donation_amount_cache_key( $this->ID ), $this->donated_amount, 0 );
905 }
906
907 $amount = $this->donated_amount;
908
909 /* If returning a string, return it in the site number format. */
910 if ( ! $sanitize ) {
911 $amount = Charitable_Currency::get_instance()->sanitize_database_amount( $amount );
912 }
913
914 /**
915 * Filter the campaign donated amount.
916 *
917 * @since 1.2.0
918 *
919 * @param string|float|WP_Error $amount The donated amount.
920 * @param Charitable_Campaign $this This campaign object.
921 * @param boolean $sanitize Whether the amount should be sanitized.
922 */
923 return apply_filters( 'charitable_campaign_donated_amount', $amount, $this, $sanitize );
924 }
925
926 /**
927 * Return the currency formatted donation amount.
928 *
929 * @since 1.6.0
930 *
931 * @return string
932 */
933 public function get_donated_amount_formatted() {
934 return charitable_format_money( $this->get_donated_amount() );
935 }
936
937 /**
938 * Return a string describing the campaign's donation summary.
939 *
940 * @since 1.0.0
941 *
942 * @return string
943 */
944 public function get_donation_summary() {
945 $currency_helper = charitable_get_currency_helper();
946 $amount = $this->get_donated_amount();
947 $goal = $this->get_meta( '_campaign_goal' );
948
949 if ( $goal ) {
950 $ret = sprintf(
951 // translators: %1$s is the amount donated, %2$s is the goal amount.
952 _x( '%1$s donated of %2$s goal', 'amount donated of goal', 'charitable' ),
953 '<span class="amount">' . $currency_helper->get_monetary_amount( $amount ) . '</span>',
954 '<span class="goal-amount">' . $currency_helper->get_monetary_amount( $goal ) . '</span>'
955 );
956 } else {
957 $ret = sprintf(
958 // translators: %s is the amount donated.
959 _x( '%s donated', 'amount donated', 'charitable' ),
960 '<span class="amount">' . $currency_helper->get_monetary_amount( $amount ) . '</span>'
961 );
962 }
963
964 /**
965 * Filter the returned string if you want to display the donation summary in a different way.
966 *
967 * @since 1.0.0
968 * @since 1.5.0 Added the $amount argument.
969 * @since 1.5.0 Added the $goal argument.
970 *
971 * @param string $ret The summary.
972 * @param Charitable_Campaign $this This campaign object.
973 * @param float $amount The amount donated.
974 * @param int $goal The campaign goal.
975 */
976 return apply_filters( 'charitable_donation_summary', $ret, $this, $amount, $goal );
977 }
978
979 /**
980 * Return a string especially for the campaign builder describing the campaign's donation summary.
981 *
982 * @since 1.8.0
983 *
984 * @return string
985 */
986 public function get_builder_donation_summary() {
987 $currency_helper = charitable_get_currency_helper();
988 $amount = $this->get_donated_amount();
989 $goal = $this->get_meta( '_campaign_goal' );
990
991 $ret = sprintf(
992 // translators: %s is the amount donated.
993 _x( '%s donated', 'amount donated', 'charitable' ),
994 '<span class="amount">' . $currency_helper->get_monetary_amount( $amount ) . '</span>'
995 );
996
997 /**
998 * Filter the returned string if you want to display the donation summary in a different way.
999 *
1000 * @since 1.8.0
1001 *
1002 * @param string $ret The summary.
1003 * @param Charitable_Campaign $this This campaign object.
1004 * @param float $amount The amount donated.
1005 * @param int $goal The campaign goal.
1006 */
1007 return apply_filters( 'charitable_builder_donation_summary', $ret, $this, $amount, $goal );
1008 }
1009
1010 /**
1011 * Return the percentage donated. Use this if you want a formatted string.
1012 *
1013 * @since 1.0.0
1014 *
1015 * @return string|false String if campaign has a goal. False if no goal is set.
1016 */
1017 public function get_percent_donated() {
1018 $percent = $this->get_percent_donated_raw();
1019
1020 if ( false === $percent ) {
1021 return $percent;
1022 }
1023
1024 $percent = number_format( $percent, 2 );
1025
1026 return apply_filters( 'charitable_percent_donated', $percent . '%', $percent, $this );
1027 }
1028
1029 /**
1030 * Returns the percentage donated as a number.
1031 *
1032 * @since 1.0.0
1033 * @version 1.8.7.1
1034 *
1035 * @return int
1036 */
1037 public function get_percent_donated_raw() {
1038 if ( ! $this->has_goal() ) {
1039 return false;
1040 }
1041
1042 $donated = (float) $this->get_donated_amount( true );
1043 $goal = (float) $this->get_goal();
1044 if ( $goal <= 0 ) {
1045 return 0;
1046 }
1047 return ( $donated / $goal ) * 100;
1048 }
1049
1050 /**
1051 * Return the number of people who have donated to the campaign.
1052 *
1053 * @since 1.0.0
1054 *
1055 * @return int
1056 */
1057 public function get_donor_count() {
1058 /**
1059 * Set the number of donors who have donated to this campaign.
1060 *
1061 * @since 1.4.7
1062 *
1063 * @param int $count Number of donors.
1064 * @param Charitable_Campaign $this This campaign object.
1065 */
1066 return apply_filters(
1067 'charitable_campaign_donor_count',
1068 (int) charitable_get_table( 'campaign_donations' )->count_campaign_donors( $this->ID ),
1069 $this
1070 );
1071 }
1072
1073 /**
1074 * Returns the donation form object.
1075 *
1076 * @since 1.0.0
1077 *
1078 * @return Charitable_Donation_Form_Interface
1079 */
1080 public function get_donation_form() {
1081 if ( ! isset( $this->donation_form ) ) {
1082 /**
1083 * Return the class name of the donation form for this campaign.
1084 *
1085 * @since 1.0.0
1086 *
1087 * @param string $class The form class.
1088 * @param Charitable_Campaign $this This campaign object.
1089 */
1090 $form_class = apply_filters( 'charitable_donation_form_class', 'Charitable_Donation_Form', $this );
1091
1092 $this->donation_form = new $form_class( $this );
1093 }
1094
1095 return $this->donation_form;
1096 }
1097
1098 /**
1099 * Returns the amount to be donated to the campaign as it is currently set in the session.
1100 *
1101 * @since 1.0.0
1102 *
1103 * @return int
1104 */
1105 public function get_donation_amount_in_session() {
1106 $donation = charitable_get_session()->get_donation_by_campaign( $this->ID );
1107 $amount = is_array( $donation ) ? $donation['amount'] : 0;
1108
1109 /**
1110 * The donation amount for this campaign stored in the session.
1111 *
1112 * @since 1.0.0
1113 *
1114 * @param float|int $amount The amount.
1115 * @param Charitable_Campaign $this This campaign object.
1116 */
1117 return apply_filters( 'charitable_session_donation_amount', $amount, $this );
1118 }
1119
1120 /**
1121 * Returns the donation period for the amount in session.
1122 *
1123 * @since 1.6.25
1124 *
1125 * @return false|string
1126 */
1127 public function get_donation_period_in_session() {
1128 $donation = charitable_get_session()->get_donation_by_campaign( $this->ID );
1129
1130 if ( ! $donation ) {
1131 return false;
1132 }
1133
1134 if ( ! is_array( $donation ) || ! array_key_exists( 'donation_period', $donation ) ) {
1135 return 'once';
1136 }
1137
1138 return $donation['donation_period'];
1139 }
1140
1141 /**
1142 * Return the initial/default donation period when
1143 *
1144 * @since 1.6.32
1145 *
1146 * @return string
1147 */
1148 public function get_initial_donation_period() {
1149 $period = $this->get_donation_period_in_session();
1150
1151 if ( false !== $period ) {
1152 return $period;
1153 }
1154
1155 if ( ! class_exists( 'Charitable_Recurring' ) ) {
1156 return 'once';
1157 }
1158
1159 switch ( $this->get( 'recurring_donation_mode' ) ) {
1160 case 'advanced':
1161 $period = 'one-time' === $this->get( 'recurring_default_tab' ) ? 'once' : 'recurring';
1162 break;
1163
1164 default:
1165 $period = 'once';
1166 }
1167
1168 return $period;
1169 }
1170
1171 /**
1172 * Get the default donation amount for this campaign.
1173 *
1174 * @since 1.6.32
1175 *
1176 * @return int
1177 */
1178 public function get_default_donation_amount() {
1179 /**
1180 * Filter the default donation amount.
1181 *
1182 * Note, the donation amount should be expressed in a format where
1183 * a period (.) is used as the decimal separator. i.e. 2.50 is
1184 * two dollars and fifty cents.
1185 *
1186 * @since 1.5.6
1187 *
1188 * @param float|int $amount The amount to be filtered. $0 by default.
1189 * @param Charitable_Campaign $campaign The instance of `Charitable_Campaign`.
1190 */
1191 return apply_filters( 'charitable_default_donation_amount', 0, $this );
1192 }
1193
1194 /**
1195 * Renders the donate button template.
1196 *
1197 * @since 1.0.0
1198 *
1199 * @return void
1200 */
1201 public function donate_button_template() {
1202 if ( ! $this->can_receive_donations() ) {
1203 return;
1204 }
1205
1206 $display_option = charitable_get_option( 'donation_form_display', 'separate_page' );
1207
1208 switch ( $display_option ) {
1209 case 'separate_page':
1210 $template_name = 'campaign/donate-button.php';
1211 break;
1212
1213 case 'same_page':
1214 $template_name = 'campaign/donate-link.php';
1215 break;
1216
1217 case 'modal':
1218 $template_name = 'campaign/donate-modal.php';
1219 break;
1220
1221 default:
1222 $template_name = apply_filters( 'charitable_donate_button_template', 'campaign/donate-button.php', $this );
1223 }
1224
1225 charitable_template( $template_name, array( 'campaign' => $this ) );
1226 }
1227
1228 /**
1229 * Renders the donate button template.
1230 *
1231 * @since 1.2.3
1232 *
1233 * @return void
1234 */
1235 public function donate_button_loop_template() {
1236 if ( ! $this->can_receive_donations() ) {
1237 return;
1238 }
1239
1240 $display_option = charitable_get_option( 'donation_form_display', 'separate_page' );
1241
1242 switch ( $display_option ) {
1243 case 'modal':
1244 $template_name = 'campaign-loop/donate-modal.php';
1245 break;
1246
1247 default:
1248 $template_name = apply_filters( 'charitable_donate_button_loop_template', 'campaign-loop/donate-link.php', $this );
1249 }
1250
1251 charitable_template( $template_name, array( 'campaign' => $this ) );
1252 }
1253
1254 /**
1255 * Returns the campaign creator.
1256 *
1257 * By default, this just returns the user from the post_author field, but
1258 * it can be overridden by plugins.
1259 *
1260 * @since 1.0.0
1261 *
1262 * @return int $user_id
1263 */
1264 public function get_campaign_creator() {
1265 return apply_filters( 'charitable_campaign_creator', $this->post->post_author, $this );
1266 }
1267
1268 /**
1269 * Return the campaign creator's name.
1270 *
1271 * @since 1.6.0
1272 *
1273 * @return string
1274 */
1275 public function get_campaign_creator_name() {
1276 return get_the_author_meta( 'display_name', $this->get_campaign_creator() );
1277 }
1278
1279 /**
1280 * Return the campaign creator's email address.
1281 *
1282 * @since 1.6.0
1283 *
1284 * @return string
1285 */
1286 public function get_campaign_creator_email() {
1287 return get_the_author_meta( 'user_email', $this->get_campaign_creator() );
1288 }
1289
1290 /**
1291 * Sanitize the campaign goal.
1292 *
1293 * @since 1.0.0
1294 *
1295 * @param string $value Current value of goal.
1296 * @return string|int
1297 */
1298 public static function sanitize_campaign_goal( $value ) {
1299 if ( empty( $value ) || ! $value ) {
1300 return 0;
1301 }
1302
1303 return charitable_get_currency_helper()->sanitize_monetary_amount( $value );
1304 }
1305
1306 /**
1307 * Sanitize the campaign minimum amount.
1308 *
1309 * @since 1.7.0.3
1310 *
1311 * @param string $value Current value of min amount.
1312 * @return string|int
1313 */
1314 public static function sanitize_min_donation_amount( $value ) {
1315 if ( empty( $value ) || ! $value ) {
1316 return 0;
1317 }
1318
1319 return charitable_get_currency_helper()->sanitize_monetary_amount( $value );
1320 }
1321
1322 /**
1323 * Sanitize the campaign end date.
1324 *
1325 * We use WP_Locale to parse the month that the user has set.
1326 *
1327 * @global WP_Locale $wp_locale
1328 *
1329 * @since 1.0.0
1330 *
1331 * @param string $value Current end date value.
1332 * @param array $submitted The submitted data.
1333 * @return string|int
1334 */
1335 public static function sanitize_campaign_end_date( $value, $submitted = array() ) {
1336 $end_time = array_key_exists( '_campaign_end_time', $submitted ) ? $submitted['_campaign_end_time'] : '23:59:59';
1337
1338 if ( charitable()->registry()->get( 'i18n' )->decline_months() ) {
1339 $end_date = $value . ' ' . $end_time;
1340 } else {
1341 $end_date = charitable_sanitize_date( $value, 'Y-m-d ' . $end_time );
1342 }
1343
1344 if ( ! $end_date ) {
1345 $end_date = 0;
1346 }
1347
1348 return $end_date;
1349 }
1350
1351 /**
1352 * Sanitize the campaign suggested donations.
1353 *
1354 * @since 1.0.0
1355 *
1356 * @param array $value Current suggested donations value.
1357 * @return array
1358 */
1359 public static function sanitize_campaign_suggested_donations_default( $value ) {
1360
1361 return $value; // this is likely an array.
1362 }
1363
1364 /**
1365 * Sanitize the campaign suggested donations.
1366 *
1367 * @since 1.0.0
1368 *
1369 * @param array $value Current suggested donations value.
1370 * @param bool $submitted Whether the value was submitted.
1371 * @param int $campaign_id The campaign ID.
1372 * @return array
1373 */
1374 public static function sanitize_campaign_suggested_donations( $value, $submitted = false, $campaign_id = false ) { // phpcs:ignore
1375 if ( ! is_array( $value ) ) {
1376 return array();
1377 }
1378
1379 $value = array_filter( $value, array( 'Charitable_Campaign', 'filter_suggested_donation' ) );
1380
1381 if ( empty( $value ) ) {
1382 return $value;
1383 }
1384
1385 foreach ( $value as $key => $suggestion ) {
1386 $value[ $key ]['amount'] = charitable_sanitize_amount( (string) $suggestion['amount'] );
1387
1388 /**
1389 * Sanitize the description field.
1390 *
1391 * @since 1.6.51
1392 *
1393 * @param boolean $sanitize Whether to sanitize the suggested amount description.
1394 * Returning false will allow HTML to be used, though it will
1395 * still be filtered using wp_kses_post.
1396 */
1397 if ( apply_filters( 'charitable_sanitize_suggested_amount_description', true ) ) {
1398 $value[ $key ]['description'] = sanitize_text_field( $suggestion['description'] );
1399 } else {
1400 $value[ $key ]['description'] = wp_kses_post( $suggestion['description'] );
1401 }
1402 }
1403
1404 return $value;
1405 }
1406
1407 /**
1408 * Filter out any suggested donations that do not have an amount set.
1409 *
1410 * @since 1.0.0
1411 *
1412 * @param array|string $donation Suggested donation or an array of suggested donations.
1413 * @return boolean
1414 */
1415 public static function filter_suggested_donation( $donation ) {
1416 if ( is_array( $donation ) ) {
1417 return isset( $donation['amount'] ) && ! empty( $donation['amount'] );
1418 }
1419
1420 return ! empty( $donation['amount'] );
1421 }
1422
1423 /**
1424 * Sanitize any checkbox value.
1425 *
1426 * @since 1.0.0
1427 *
1428 * @param mixed $value Current checkbox value.
1429 * @return boolean
1430 */
1431 public static function sanitize_checkbox( $value ) {
1432 return intval( true == $value || 'on' === $value );
1433 }
1434
1435 /**
1436 * Sanitize the campaign description.
1437 *
1438 * @since 1.0.0
1439 * @updated 1.7.0.4
1440 *
1441 * @param string $value Current description value.
1442 * @return string
1443 */
1444 public static function sanitize_campaign_description( $value ) {
1445
1446 /**
1447 * Allowed HTML in description.
1448 */
1449 $wp_kses_allowed_html = array(
1450 'a' => array(
1451 'href' => array(),
1452 'target' => array(),
1453 'class' => array(),
1454 'title' => array(),
1455 ),
1456 'br' => array(),
1457 'img' => array(
1458 'src' => array(),
1459 'class' => array(),
1460 'alt' => array(),
1461 ),
1462 'h1' => array(
1463 'class' => array(),
1464 ),
1465 'h2' => array(
1466 'class' => array(),
1467 ),
1468 'h3' => array(
1469 'class' => array(),
1470 ),
1471 'h4' => array(
1472 'class' => array(),
1473 ),
1474 'h5' => array(
1475 'class' => array(),
1476 ),
1477 'h6' => array(
1478 'class' => array(),
1479 ),
1480 'div' => array(
1481 'class' => array(),
1482 ),
1483 'p' => array(
1484 'style' => array(),
1485 'class' => array(),
1486 ),
1487 'ul' => array(
1488 'class' => array(),
1489 ),
1490 'li' => array(
1491 'id' => array(),
1492 'class' => array(),
1493 ),
1494 'em' => array(),
1495 'span' => array(
1496 'class' => array(),
1497 ),
1498 'strong' => array(),
1499 );
1500
1501 if ( apply_filters( 'charitable_sanitize_campaign_description', false ) ) {
1502 return sanitize_text_field( $value );
1503 } else {
1504 return wp_kses( apply_filters( 'charitable_campaign_description', $value ), apply_filters( 'charitable_sanitize_campaign_description_allowed_html', $wp_kses_allowed_html ) );
1505 }
1506 }
1507
1508 /**
1509 * Sanitize the campaign donation button text..
1510 *
1511 * @since 1.7.0.9
1512 *
1513 * @param string $value Current text value.
1514 * @return string
1515 */
1516 public static function sanitize_campaign_donate_button_text( $value = false ) {
1517
1518 return wp_strip_all_tags( $value );
1519 }
1520
1521 /**
1522 * Sanitize the value provided for custom donations.
1523 *
1524 * @since 1.3.6
1525 * @version 1.8.0
1526 *
1527 * @param mixed $value Current custom donations value.
1528 * @param array $submitted All posted values.
1529 * @return boolean
1530 */
1531 public static function sanitize_custom_donations( $value, $submitted ) {
1532 $checked = self::sanitize_checkbox( $value );
1533
1534 if ( $checked ) {
1535 return $checked;
1536 }
1537
1538 /**
1539 * Filter whether a campaign can be saved with custom donations disabled
1540 * and no suggested donations.
1541 *
1542 * @since 1.6.14
1543 *
1544 * @param boolean $permitted Whether a campaign is permitted to be saved without
1545 * suggested donations or custom donations.
1546 * @param array $submitted The submitted values.
1547 */
1548 if ( apply_filters( 'charitable_campaign_permitted_without_custom_or_suggested', false, $submitted ) ) {
1549 return $checked;
1550 }
1551
1552 // see if literally "0" was passed.
1553 if ( is_string( $value ) && '0' === $value ) {
1554 return 0;
1555 }
1556
1557 /* If suggested donations are not set, custom donations needs to be enabled. */
1558 if ( ! isset( $submitted['_campaign_suggested_donations'] ) ) {
1559 return 1;
1560 }
1561
1562 $suggested_donations = self::sanitize_campaign_suggested_donations( $submitted['_campaign_suggested_donations'] );
1563
1564 if ( empty( $suggested_donations ) ) {
1565 return 1;
1566 }
1567
1568 return $checked;
1569 }
1570
1571 /**
1572 * Flush donations cache.
1573 *
1574 * @since 1.0.0
1575 *
1576 * @param int $campaign_id The campaign ID.
1577 * @return void
1578 */
1579 public static function flush_donations_cache( $campaign_id ) {
1580 delete_transient( self::get_donations_cache_key( $campaign_id ) );
1581 delete_transient( self::get_donation_amount_cache_key( $campaign_id ) );
1582
1583 do_action( 'charitable_flush_campaign_cache', $campaign_id );
1584 }
1585
1586 /**
1587 * Returns the key used for caching all donations made to this campaign.
1588 *
1589 * @since 1.0.0
1590 *
1591 * @param int $campaign_id The ID of the campaign.
1592 * @return string
1593 */
1594 private static function get_donations_cache_key( $campaign_id ) {
1595 return 'charitable_campaign_' . $campaign_id . '_donations';
1596 }
1597
1598 /**
1599 * Returns the key used for caching the donation amount for this campaign.
1600 *
1601 * @since 1.0.0
1602 *
1603 * @param int $campaign_id The ID of the campaign.
1604 * @return string
1605 */
1606 private static function get_donation_amount_cache_key( $campaign_id ) {
1607 return 'charitable_campaign_' . $campaign_id . '_donation_amount';
1608 }
1609
1610 /**
1611 * Deprecated method used to sanitize meta.
1612 *
1613 * @deprecated 1.7.0
1614 *
1615 * @since 1.4.12 Deprecated.
1616 *
1617 * @param mixed $value Value of meta field.
1618 * @param string $key Key of meta field.
1619 * @param array $submitted Posted values.
1620 */
1621 public static function sanitize_meta( $value, $key, $submitted ) {
1622 charitable_get_deprecated()->deprecated_function( __METHOD__, '1.4.2' );
1623 return apply_filters( 'charitable_sanitize_campaign_meta' . $key, $value, $submitted );
1624 }
1625 }
1626
1627 endif;
1628