PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.3.1
GiveWP – Donation Plugin and Fundraising Platform v3.3.1
4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / donors / class-give-donor-wall.php
give / includes / donors Last commit date
actions.php 3 years ago backward-compatibility.php 7 years ago class-give-donor-stats.php 6 years ago class-give-donor-wall.php 2 years ago class-give-donors-query.php 5 years ago frontend-donor-functions.php 3 years ago
class-give-donor-wall.php
667 lines
1 <?php
2 /**
3 * Donor Wall
4 *
5 * @package Give
6 * @subpackage Classes/Give_Donor_Wall
7 * @copyright Copyright (c) 2020, GiveWP
8 * @license https://opensource.org/licenses/gpl-license GNU Public License
9 * @since 1.0
10 */
11
12 // Exit if accessed directly.
13 use Give\Donations\ValueObjects\DonationMetaKeys;
14
15 if (!defined('ABSPATH')) {
16 exit;
17 }
18
19
20 /**
21 * Give_Donor_Wall Class
22 *
23 * This class handles donors.
24 *
25 * @since 2.2.0
26 */
27 class Give_Donor_Wall {
28
29 /**
30 * Instance.
31 *
32 * @since 2.2.0
33 * @access private
34 * @var Give_Donor_Wall
35 */
36 private static $instance;
37
38 /**
39 * Singleton pattern.
40 *
41 * @since 2.2.0
42 * @access private
43 */
44 private function __construct() {
45 }
46
47
48 /**
49 * Get instance.
50 *
51 * @since 2.2.0
52 * @access public
53 * @return Give_Donor_Wall
54 */
55 public static function get_instance() {
56 if ( null === static::$instance ) {
57 self::$instance = new static();
58
59 self::$instance->setup_actions();
60 }
61
62 return self::$instance;
63 }
64
65 /**
66 * Setup the default hooks and actions
67 *
68 * @since 2.2.0
69 *
70 * @return void
71 */
72 public function setup_actions() {
73
74 add_shortcode( 'give_donor_wall', [ $this, 'render_shortcode' ] );
75
76 add_action( 'wp_ajax_give_get_donor_comments', [ $this, 'ajax_handler' ] );
77 add_action( 'wp_ajax_nopriv_give_get_donor_comments', [ $this, 'ajax_handler' ] );
78
79 }
80
81
82 /**
83 * Displays donors in a grid layout.
84 *
85 * @since 2.27.0 Moved AJAX nonce verification to ajax_handler method.
86 * @since 2.2.0
87 *
88 * @param array $atts {
89 * Optional. Attributes of the donor wall shortcode.
90 *
91 * @type int $donors_per_page Number of donors per page. Default '20'.
92 * @type int $form_id The donation form to filter donors by. Default is all forms (no filter).
93 * @type bool $paged Whether to paginate donors. Default 'true'.
94 * @type string $ids A comma-separated list of donor IDs to display. Default empty.
95 * @type string $columns Maximum columns to display. Default 'best-fit'.
96 * Accepts 'best-fit', '1', '2', '3', '4'.
97 * @type bool $show_avatar Whether to display the donor's gravatar image if available. Default 'true'.
98 * @type bool $show_name Whether to display the donor's full name, first and last. Default 'true'.
99 * @type bool $show_company_name Whether to display the donor's company name. Default 'false'.
100 * @type bool $show_total Whether to display the donor's donation amount. Default 'true'.
101 * @type bool $show_comments Whether to display the donor's comment if they left one. Default 'true'.
102 * @type int $comment_length The number of words to display for the comments before a "Read more" field
103 * @type int $only_comments Whether to display the donors only with comment. Default 'false'.
104 * @type bool $show_time Whether to display date of the last donation. Default 'true'.
105 *
106 * @type string $readmore_text Link label for modal in which donor can read full comment.
107 * @type string $loadmore_text Button label which will load more donor comments.
108 * @type int $avatar_size Avatar image size in pixels without the "px". Default "75"
109 * @type string $orderby The order in which you want the donations to appear.
110 * Currently we are using this attribute internally and, it will sort donations by created date.
111 * @type string $order The order in which you want the donors to appear. Accepts "ASC". "DESC".
112 *
113 * }
114 * @return string|bool The markup of the form grid or false.
115 */
116 public function render_shortcode( $atts ) {
117
118 $give_settings = give_get_settings();
119
120 $atts = $this->parse_atts( $atts );
121
122 _give_redirect_form_id($atts['form_id']);
123
124 $donations = $this->get_donation_data( $atts );
125 $html = '';
126
127 if ( $donations ) {
128
129 ob_start();
130
131 foreach ( $donations as $donation ) {
132 $donor = new Give_Donor($donation['_give_payment_donor_id']);
133 // Give/templates/shortcode-donor-wall.php.
134 give_get_template(
135 'shortcode-donor-wall',
136 [
137 $donation,
138 $give_settings,
139 $atts,
140 $donor
141 ]
142 );
143 }
144
145 $html = ob_get_clean();
146
147 // Return only donor html.
148 if (
149 isset( $atts['only_donor_html'] )
150 && wp_doing_ajax()
151 && $atts['only_donor_html']
152 ) {
153 return $html;
154 }
155 }
156
157 $temp_atts = $atts;
158 $temp_atts['paged'] = $atts['paged'] + 1;
159
160 $more_btn_html = sprintf(
161 '<input type="hidden" class="give-donor-wall-shortcode-attrs" data-shortcode="%s" data-nonce="%s">',
162 rawurlencode( http_build_query( $atts ) ),
163 wp_create_nonce( 'givewp-donor-wall-more' )
164 );
165
166 if ( $this->has_donations( $temp_atts ) ) {
167 $more_btn_html .= sprintf(
168 '<button class="give-donor__load_more give-button-with-loader"><span class="give-loading-animation"></span>%1$s</button>',
169 $atts['loadmore_text']
170 );
171 }
172
173 $html = $html
174 ? sprintf(
175 '<div class="give-wrap give-grid-ie-utility"><div class="give-grid give-grid--%1$s">%2$s</div>%3$s</div>',
176 esc_attr( $atts['columns'] ),
177 $html,
178 $more_btn_html
179 )
180 : '';
181
182 return $html;
183 }
184
185 /**
186 * Parse shortcode attributes
187 *
188 * @since 2.30.0
189 * @since 2.2.0
190 * @access public
191 *
192 * @param array $atts Shortcode attributes.
193 *
194 * @return array
195 */
196 public function parse_atts( $atts ) {
197 $atts = shortcode_atts(
198 [
199 'donors_per_page' => 12,
200 'form_id' => 0,
201 'paged' => 1,
202 'ids' => '',
203 'cats' => '',
204 'tags' => '',
205 'columns' => '3',
206 'anonymous' => true,
207 'show_avatar' => true,
208 'show_name' => true,
209 'show_company_name' => false,
210 'show_form' => false,
211 'show_total' => true,
212 'show_comments' => true,
213 'show_tributes' => true,
214 'comment_length' => 140,
215 'only_comments' => false,
216 'readmore_text' => esc_html__( 'Read more', 'give' ),
217 'loadmore_text' => esc_html__( 'Load more', 'give' ),
218 'avatar_size' => 75,
219 'color' => "#219653",
220 'orderby' => 'post_date',
221 'order' => 'DESC',
222 'hide_empty' => true, // Deprecated in 2.3.0
223 'only_donor_html' => false, // Only for internal use.,
224 'show_time' => true,
225 ],
226 $atts,
227 'give_donor_wall'
228 );
229
230 // Validate boolean attributes.
231 $boolean_attributes = [
232 'anonymous',
233 'show_avatar',
234 'show_name',
235 'show_company_name',
236 'show_total',
237 'show_comments',
238 'show_tributes',
239 'hide_empty',
240 'only_comments',
241 'only_donor_html',
242 'show_time'
243 ];
244
245 foreach ( $boolean_attributes as $att ) {
246 // Convert numeric to boolean.
247 // It will prevent condition check against boolean value.
248 if ( is_numeric( $atts[ $att ] ) ) {
249 $atts[ $att ] = (bool) $atts[ $att ];
250 }
251
252 $atts[ $att ] = filter_var( $atts[ $att ], FILTER_VALIDATE_BOOLEAN );
253 }
254
255 // Validate numeric attributes.
256 $numeric_attributes = [
257 'donors_per_page',
258 'paged',
259 'comment_length',
260 'avatar_size',
261 ];
262
263 foreach ( $numeric_attributes as $att ) {
264 // It will prevent condition check against numeric value.
265 $atts[ $att ] = absint( $atts[ $att ] );
266 }
267
268 // Validate comma separated numeric attributes and keep original data format ( comma separated string).
269 if ( ! empty( $atts['ids'] ) ) {
270 $atts['ids'] = implode( ',', $this->split_string($atts['ids'], 'absint') );
271 }
272
273 // Validate Form IDs
274 if ( ! empty( $atts['form_id'] ) ) {
275 $atts['form_id'] = implode( ',', $this->split_string($atts['form_id'], 'absint') );
276 }
277
278 // Donation form categories
279 if ( ! empty( $atts['cats'] ) ) {
280 $atts['cats'] = $this->split_string($atts['cats']);
281 }
282
283 // Donation form tags
284 if ( ! empty( $atts['tags'] ) ) {
285 $atts['tags'] = $this->split_string($atts['tags']);
286 }
287
288 return $atts;
289 }
290
291 /**
292 * Get donors
293 *
294 * @since 2.2.0
295 * @access public
296 *
297 * @param array $donor_query Donor query.
298 *
299 * @return array
300 */
301 public function get_donors( $donor_query ) {
302 $donor_query = new Give_Donors_Query( $donor_query );
303
304 return $donor_query->get_donors();
305 }
306
307
308 /**
309 * This function should return donor comment for ajax request.
310 *
311 * @since 2.27.0 Check nonce for AJAX request to prevent scrapping, see https://github.com/impress-org/givewp/issues/6374.
312 * @since 2.2.0
313 * @access public
314 */
315 public function ajax_handler() {
316 $shortcode_atts = array_map( 'give_clean', wp_parse_args( rawurldecode( $_POST['data'] ) ) ); // @codingStandardsIgnoreLine
317
318 // Get next page donor comments.
319 $shortcode_atts['paged'] = $shortcode_atts['paged'] + 1;
320 $shortcode_atts['only_donor_html'] = true;
321
322 check_ajax_referer( 'givewp-donor-wall-more', 'nonce' );
323
324 $donors_comment_html = $this->render_shortcode( $shortcode_atts );
325
326 // Check if donor comment remaining.
327 $temp_atts = $shortcode_atts;
328 $temp_atts['paged'] = $shortcode_atts['paged'] + 1;
329 $has_donors = $this->has_donations( $temp_atts ) ? 1 : 0;
330
331 // Remove internal shortcode param.
332 unset( $shortcode_atts['only_donor_html'] );
333
334 wp_send_json(
335 [
336 'shortcode' => rawurlencode( http_build_query( $shortcode_atts ) ),
337 'html' => $donors_comment_html,
338 'remaining' => $has_donors,
339 ]
340 );
341 }
342
343 /**
344 * Get query params
345 *
346 * @since 2.24.1
347 * @since 2.3.0
348 *
349 * @param array $atts
350 *
351 * @return array
352 */
353 private function get_query_param( $atts = [] ) {
354 $valid_order = [ 'ASC', 'DESC' ];
355 $valid_orderby = [ 'post_date', 'donation_amount' ];
356
357 $query_atts = [];
358
359 $query_atts['order'] = in_array( $atts['order'], $valid_order ) ? $atts['order'] : 'DESC';
360 $query_atts['orderby'] = in_array( $atts['orderby'], $valid_orderby ) ? $atts['orderby'] : 'post_date';
361 $query_atts['limit'] = absint( $atts['donors_per_page'] );
362 $query_atts['offset'] = absint( $atts['donors_per_page'] * ( $atts['paged'] - 1 ) );
363 $query_atts['form_id'] = implode( '\',\'', array_map( 'absint', explode( ',', $atts['form_id'] ) ) );
364 $query_atts['ids'] = implode( '\',\'', array_map( 'absint', explode( ',', $atts['ids'] ) ) );
365 $query_atts['cats'] = $atts['cats'];
366 $query_atts['tags'] = $atts['tags'];
367 $query_atts['only_comments'] = ( true === $atts['only_comments'] );
368 $query_atts['anonymous'] = ( true === $atts['anonymous'] );
369
370 return $query_atts;
371 }
372
373 /**
374 * Get donation data.
375 *
376 * @since 2.27.0 Change to read comment from donations meta table
377 * @since 2.3.0
378 *
379 * @param array $atts
380 *
381 * @return array
382 */
383 private function get_donation_data( $atts = [] ) {
384 global $wpdb;
385
386 // Bailout if donation does not exist.
387 if ( ! ( $donation_ids = $this->get_donations( $atts ) ) ) {
388 return [];
389 }
390
391 $donation_ids = ! empty( $donation_ids )
392 ? '\'' . implode( '\',\'', $donation_ids ) . '\''
393 : '';
394
395 // Backward compatibility
396 $donation_id_col = Give()->payment_meta->get_meta_type() . '_id';
397
398 $sql = "SELECT m1.*, p1.post_date as donation_date FROM {$wpdb->donationmeta} as m1
399 INNER JOIN {$wpdb->posts} as p1 ON (m1.{$donation_id_col}=p1.ID)
400 WHERE m1.{$donation_id_col} IN ( {$donation_ids} )
401 ORDER BY FIELD( p1.ID, {$donation_ids} )
402 ";
403
404 $results = (array) $wpdb->get_results( $sql );
405
406 if ( ! empty( $results ) ) {
407 $temp = [];
408
409 /* @var stdClass $result */
410 foreach ( $results as $result ) {
411 $temp[ $result->{$donation_id_col} ][ $result->meta_key ] = maybe_unserialize( $result->meta_value );
412
413 // Set donation date.
414 if ( empty( $temp[ $result->{$donation_id_col} ]['donation_date'] ) ) {
415 $temp[ $result->{$donation_id_col} ]['donation_date'] = $result->donation_date;
416 }
417 }
418
419 if ( ! empty( $temp ) ) {
420 foreach ( $temp as $donation_id => $donation_data ) {
421 $temp[ $donation_id ]['donation_id'] = $donation_id;
422
423 $temp[ $donation_id ]['name_initial'] = give_get_name_initial(
424 [
425 'firstname' => $donation_data['_give_donor_billing_first_name'],
426 'lastname' => $donation_data['_give_donor_billing_last_name'],
427 ]
428 );
429
430 $temp[$donation_id]['donor_comment'] = give_get_payment_meta(
431 $donation_id,
432 DonationMetaKeys::COMMENT
433 );
434 }
435 }
436
437 $results = ! empty( $temp ) ? $temp : [];
438 }
439
440 return $results;
441 }
442
443 /**
444 * Get donation list for specific query
445 *
446 * @since 2.3.0
447 *
448 * @param array $atts
449 *
450 * @return array
451 */
452 private function get_donations( $atts = [] ) {
453 global $wpdb;
454
455 // Backward compatibility
456 $donation_id_col = Give()->payment_meta->get_meta_type() . '_id';
457
458 $query_params = $this->get_query_param( $atts );
459
460 $sql = "SELECT p1.ID FROM {$wpdb->posts} as p1";
461 $where = " WHERE p1.post_status IN ('publish') AND p1.post_type = 'give_payment'";
462
463 // exclude donation with zero amount from result.
464 $sql .= " INNER JOIN {$wpdb->donationmeta} as m1 ON (p1.ID = m1.{$donation_id_col})";
465 $where .= " AND m1.meta_key='_give_payment_total' AND m1.meta_value>0";
466
467 if ( $query_params['form_id'] ) {
468 $sql .= " INNER JOIN {$wpdb->donationmeta} as m2 ON (p1.ID = m2.{$donation_id_col})";
469 $where .= " AND m2.meta_key='_give_payment_form_id' AND m2.meta_value IN ('{$query_params['form_id']}')";
470 }
471
472 // Get donations only from specific donors.
473 if ( $query_params['ids'] ) {
474 $sql .= " INNER JOIN {$wpdb->donationmeta} as m3 ON (p1.ID = m3.{$donation_id_col})";
475 $where .= " AND m3.meta_key='_give_payment_donor_id' AND m3.meta_value IN ('{$query_params['ids']}')";
476 }
477
478 // exclude donations which does not has donor comment.
479 if ( $query_params['only_comments'] ) {
480 $sql .= " INNER JOIN {$wpdb->give_comments} as gc1 ON (p1.ID = gc1.comment_parent)";
481 $where .= " AND gc1.comment_type='donor_donation'";
482 }
483
484 // exclude anonymous donation form query based on query parameters.
485 if (
486 ! $query_params['anonymous']
487 || $query_params['only_comments']
488 ) {
489 $where .= " AND p1.ID NOT IN ( SELECT DISTINCT({$donation_id_col}) FROM {$wpdb->donationmeta} WHERE meta_key='_give_anonymous_donation' AND meta_value='1')";
490 }
491
492 // Handle Taxonomy
493 $args = [
494 'post_type' => 'give_forms',
495 'posts_per_page' => -1,
496 'fields' => 'ids',
497 'tax_query' => [],
498 ];
499
500 // Categories
501 if ( is_array($atts['cats'])) {
502 $args['tax_query']['conditions'] = ['relation' => 'OR'];
503
504 foreach ($atts['cats'] as $category) {
505 $args['tax_query']['conditions'][] = [
506 'operator' => 'IN',
507 'taxonomy' => 'give_forms_category',
508 'field' => 'slug',
509 'terms' => $category,
510 ];
511 }
512 }
513
514 // Tags
515 if ( is_array($atts['tags'])) {
516 if (empty($args['tax_query'])) {
517 $args['tax_query']['conditions'] = ['relation' => 'OR'];
518 }
519
520 foreach($atts['tags'] as $tag) {
521 $args['tax_query']['conditions'][] = [
522 'operator' => 'IN',
523 'taxonomy' => 'give_forms_tag',
524 'field' => 'slug',
525 'terms' => $tag,
526 ];
527 }
528 }
529
530 if ( ! empty( $args['tax_query'] ) ) {
531 $query = new WP_Query( $args );
532
533 if ( ! empty($query->posts) ) {
534 $form_ids = implode("','", $query->posts );
535 $sql .= " INNER JOIN {$wpdb->donationmeta} as m4 ON (p1.ID = m4.{$donation_id_col})";
536 $where .= " AND m4.meta_key='_give_payment_form_id' AND m4.meta_value IN ('{$form_ids}')";
537 }
538 }
539
540 // order by query based on parameter.
541 if ( 'donation_amount' === $query_params['orderby'] ) {
542 $order = " ORDER BY m1.meta_value+0 {$query_params['order']}";
543 } else {
544 $order = " ORDER BY p1.{$query_params['orderby']} {$query_params['order']}, p1.ID {$query_params['order']}";
545 }
546
547 $limit = " LIMIT {$query_params['limit']}";
548 $offset = " OFFSET {$query_params['offset']}";
549
550 $sql .= $where . $order . $limit . $offset;
551
552 return $wpdb->get_col( $sql );
553 }
554
555 /**
556 * Get donor comments
557 *
558 * @since 2.3.0
559 *
560 * @param array $donations_data
561 *
562 * @return array
563 */
564 private function get_donor_comments( $donations_data = [] ) {
565 global $wpdb;
566 $comments = [];
567
568 // Bailout.
569 if ( empty( $donations_data ) ) {
570 return $comments;
571 }
572
573 // Backward compatibility.
574 if (
575 ! give_has_upgrade_completed( 'v230_move_donor_note' )
576 || ! give_has_upgrade_completed( 'v230_move_donation_note' )
577 ) {
578 foreach ( $donations_data as $id => $data ) {
579 $comment = give_get_donor_donation_comment( $id, $data['_give_payment_donor_id'] );
580 $comments[ $id ] = ! empty( $comment ) ? $comment->comment_content : '';
581 }
582
583 return $comments;
584 }
585
586 $sql = "SELECT c1.comment_parent as donation_id, c1.comment_content as comment FROM {$wpdb->give_comments} as c1";
587 $sql .= " INNER JOIN {$wpdb->give_commentmeta} as cm1 ON (c1.comment_ID=cm1.give_comment_id)";
588 $where = [];
589
590 foreach ( $donations_data as $id => $data ) {
591 // Do not fetch comment for anonymous donation.
592 if ( ! empty( $data['_give_anonymous_donation'] ) ) {
593 continue;
594 }
595
596 $where[] = "(c1.comment_parent={$id} AND cm1.meta_key='_give_donor_id' AND cm1.meta_value={$data['_give_payment_donor_id']})";
597 }
598
599 $where = ' WHERE ' . implode( ' OR ', $where );
600 $where .= " AND c1.comment_type='donor_donation'";
601
602 $sql = $sql . $where;
603
604 $comments = (array) $wpdb->get_results( $sql );
605
606 if ( ! empty( $comments ) ) {
607 $comments = array_combine(
608 wp_list_pluck( $comments, 'donation_id' ),
609 wp_list_pluck( $comments, 'comment' )
610 );
611 }
612
613 return $comments;
614 }
615
616 /**
617 * Check if donation exist or not for specific query
618 *
619 * @since 2.3.0
620 *
621 * @param array $atts
622 *
623 * @return bool
624 */
625 private function has_donations( $atts = [] ) {
626 return (bool) $this->get_donations( $atts );
627 }
628
629 /**
630 * @since 2.20.0
631 *
632 * @param string $string
633 * @param null|callable $filter
634 * @param string $separator
635 *
636 * @return array
637 */
638 private function split_string($string, $filter = null, $separator = ',') {
639 if ( false === strpos( $string, $separator ) ) {
640 $string = trim( $string );
641
642 if (is_callable($filter)) {
643 $string = $filter($string);
644 }
645
646 return [$string];
647 }
648
649 return array_filter(
650 array_map(
651 static function( $value ) use ($filter) {
652 $value = trim( $value );
653
654 if (is_callable($filter)) {
655 return $filter($value);
656 }
657 return $value;
658 },
659 explode( $separator, $string )
660 )
661 );
662 }
663 }
664
665 // Initialize shortcode.
666 Give_Donor_Wall::get_instance();
667