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