PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.7.0.11
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.7.0.11
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 / abstracts / abstract-class-charitable-query.php

abstract-class-charitable-query.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.7.0.11, at includes/abstracts/abstract-class-charitable-query.php

1,087 lines 24.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * An abstract base class defining common methods used by Charitable queries.
4 *
5 * @package Charitable/Classes/Charitable_Query
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.8
11 */
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 if ( ! class_exists( 'Charitable_Query' ) ) :
19
20 /**
21 * Charitable_Query
22 *
23 * @since 1.0.0
24 */
25 abstract class Charitable_Query implements Iterator {
26
27 /**
28 * User-defined arguments.
29 *
30 * @var array
31 */
32 protected $args;
33
34 /**
35 * Internal iterator position.
36 *
37 * @var int
38 */
39 protected $position = 0;
40
41 /**
42 * The raw query results.
43 *
44 * @var array
45 */
46 protected $query;
47
48 /**
49 * Number of items found.
50 *
51 * @var int|null
52 */
53 protected $found_items;
54
55 /**
56 * Result set.
57 *
58 * @var array
59 */
60 protected $results;
61
62 /**
63 * Parameters to pass to the query.
64 *
65 * @var mixed[]
66 */
67 protected $parameters = array();
68
69 /**
70 * Meta SQL query.
71 *
72 * @since 1.6.5
73 *
74 * @var array|false
75 */
76 protected $meta_sql;
77
78 /**
79 * Return the query argument value for the given key.
80 *
81 * @since 1.0.0
82 *
83 * @param string $key The key of the argument.
84 * @param mixed $fallback Default value to fall back to.
85 * @return mixed|false Returns fallback if the argument is not found.
86 */
87 public function get( $key, $fallback = false ) {
88 return isset( $this->args[ $key ] ) ? $this->args[ $key ] : $fallback;
89 }
90
91 /**
92 * Set the query argument for the given key.
93 *
94 * @since 1.0.0
95 *
96 * @param string $key Key of argument to set.
97 * @param mixed $value Value to be set.
98 * @return void
99 */
100 public function set( $key, $value ) {
101 $this->args[ $key ] = apply_filters( 'charitable_query_sanitize_argument_' . $key, $value, $this );
102 }
103
104 /**
105 * Remove the given query argument.
106 *
107 * @since 1.0.0
108 *
109 * @param string $key Key of argument to remove.
110 * @return void
111 */
112 public function remove( $key ) {
113 unset( $this->args[ $key ] );
114 }
115
116 /**
117 * Return the results of the query.
118 *
119 * @global WPDB $wpdb
120 *
121 * @since 1.6.8
122 *
123 * @return object[]
124 */
125 public function get_query() {
126 if ( ! isset( $this->query ) ) {
127 /**
128 * Fires right before the query is executed.
129 *
130 * @since 1.0.0
131 *
132 * @param Charitable_Query The `Charitable_Query` instance.
133 */
134 do_action( 'charitable_pre_query', $this );
135
136 $this->query = $this->run_query( $this->get( 'output' ) );
137 $this->found_items = $this->get_found_items();
138
139 /**
140 * Fires right after the query is executed.
141 *
142 * @since 1.0.0
143 *
144 * @param Charitable_Query The `Charitable_Query` instance.
145 */
146 do_action( 'charitable_post_query', $this );
147
148 }//end if
149
150 return $this->query;
151 }
152
153 /**
154 * Return the results.
155 *
156 * @since 1.6.8
157 *
158 * @return object[]
159 */
160 public function get_results() {
161 return $this->results;
162 }
163
164 /**
165 * Return the results of the query.
166 *
167 * @global WPDB $wpdb
168 *
169 * @since 1.0.0
170 *
171 * @return object[]
172 */
173 public function query() {
174 return $this->get_query();
175 }
176
177 /**
178 * Run query, returning the results.
179 *
180 * @global WPDB $wpdb
181 *
182 * @since 1.5.0
183 *
184 * @param string $output The output type.
185 * @return array
186 */
187 public function run_query( $output ) {
188 if ( method_exists( $this, 'run_query_' . $output ) ) {
189 return call_user_func( array( $this, 'run_query_' . $output ) );
190 }
191
192 global $wpdb;
193
194 $sql = "SELECT {$this->fields()} {$this->from()} {$this->join()} {$this->where()} {$this->groupby()} {$this->orderby()} {$this->order()} {$this->limit()} {$this->offset()};";
195
196 //echo $sql;
197
198 return $wpdb->get_results( $this->get_prepared_sql( $sql ) );
199 }
200
201 /**
202 * Run count query, returning the results.
203 *
204 * @global WPDB $wpdb
205 *
206 * @since 1.5.0
207 *
208 * @return array
209 */
210 public function run_query_count() {
211 global $wpdb;
212
213 $sql = "SELECT {$this->select_count()} {$this->from()} {$this->join()} {$this->where()};";
214
215 return array( $wpdb->get_var( $this->get_prepared_sql( $sql ) ) );
216 }
217
218 /**
219 * Prepare a query with any passed parameters.
220 *
221 * @global WPDB $wpdb
222 *
223 * @since 1.5.0
224 *
225 * @param string $sql The SQL query with placeholders.
226 * @return string
227 */
228 public function get_prepared_sql( $sql ) {
229 global $wpdb;
230
231 if ( empty( $this->parameters ) ) {
232 return $sql;
233 }
234
235 return $wpdb->prepare( $sql, $this->parameters );
236 }
237
238 /**
239 * After a query has been executed, check how many found rows there are.
240 *
241 * @global WPDB $wpdb
242 *
243 * @since 1.5.0
244 *
245 * @return int
246 */
247 public function get_found_items() {
248 global $wpdb;
249
250 if ( empty( $this->query ) ) {
251 return 0;
252 }
253
254 if ( 'count' == $this->get( 'output' ) ) {
255 return current( $this->query );
256 }
257
258 if ( $this->show_all() ) {
259 return count( $this->query );
260 }
261
262 /**
263 * Filters the query used to retrieve the query result count.
264 *
265 * @since 1.5.0
266 *
267 * @param string $found_customers_query SQL query. Default 'SELECT FOUND_ROWS()'.
268 * @param Charitable_Query $query The `Charitable_Query` instance.
269 */
270 $found_items_query = apply_filters( 'charitable_found_items_query', 'SELECT FOUND_ROWS()', $this );
271
272 return (int) $wpdb->get_var( $found_items_query );
273 }
274
275 /**
276 * Return the count query right after the SELECT part of the query.
277 *
278 * This is used instead of Charitable_Query::fields and is only appropriate
279 * when all you want to do with a query is get the number of something.
280 *
281 * @global WPBD $wpdb
282 *
283 * @since 1.5.0
284 *
285 * @return string
286 */
287 public function select_count() {
288 global $wpdb;
289
290 /**
291 * Filter the `SELECT COUNT` statement.
292 *
293 * @since 1.5.0
294 *
295 * @param string $sql The `SELECT COUNT` statement.
296 * @param Charitable_Query $query The `Charitable_Query` instance.
297 */
298 return apply_filters( 'charitable_select_count_fields', "COUNT(DISTINCT {$wpdb->posts}.ID)", $this );
299 }
300
301 /**
302 * Return the fields right after the SELECT part of the query.
303 *
304 * @global WPBD $wpdb
305 *
306 * @since 1.0.0
307 *
308 * @return string
309 */
310 public function fields() {
311 global $wpdb;
312
313 $found_rows = $this->show_all() ? '' : 'SQL_CALC_FOUND_ROWS';
314
315 /**
316 * Filter the `SELECT` statement.
317 *
318 * @since 1.0.0
319 *
320 * @param string $sql The `SELECT` statement.
321 * @param Charitable_Query $query The `Charitable_Query` instance.
322 */
323 return apply_filters( 'charitable_query_fields', "$found_rows {$wpdb->posts}.ID", $this );
324 }
325
326 /**
327 * Return the FROM part of the query.
328 *
329 * @global WPBD $wpdb
330 *
331 * @since 1.0.0
332 *
333 * @return string
334 */
335 public function from() {
336 global $wpdb;
337
338 /**
339 * Filter the `FROM` statement.
340 *
341 * @since 1.0.0
342 *
343 * @param string $sql The `FROM` statement.
344 * @param Charitable_Query $query The `Charitable_Query` instance.
345 */
346 return apply_filters( 'charitable_query_from', "FROM $wpdb->posts", $this );
347 }
348
349 /**
350 * Return the JOIN part of the query.
351 *
352 * @since 1.0.0
353 *
354 * @return string
355 */
356 public function join() {
357 /**
358 * Filter the `JOIN` statement.
359 *
360 * @since 1.0.0
361 *
362 * @param string $sql The `JOIN` statement. Empty by default.
363 * @param Charitable_Query $query The `Charitable_Query` instance.
364 */
365 return apply_filters( 'charitable_query_join', '', $this );
366 }
367
368 /**
369 * Return the WHERE part of the query.
370 *
371 * @since 1.0.0
372 *
373 * @return string
374 */
375 public function where() {
376 /**
377 * Filter the `WHERE` statement.
378 *
379 * @since 1.0.0
380 *
381 * @param string $sql The `WHERE` statement.
382 * @param Charitable_Query $query This query object.
383 */
384 return apply_filters( 'charitable_query_where', 'WHERE 1=1 ', $this );
385 }
386
387 /**
388 * Return the GROUPBY part of the query.
389 *
390 * @since 1.0.0
391 *
392 * @return string
393 */
394 public function groupby() {
395 /**
396 * Filter the `GROUP BY` statement.
397 *
398 * @since 1.0.0
399 *
400 * @param string $sql The `GROUP BY` statement. Empty by default.
401 * @param Charitable_Query $query This query object.
402 */
403 return apply_filters( 'charitable_query_groupby', '', $this );
404 }
405
406 /**
407 * Return the ORDER BY part of the query.
408 *
409 * @global WPBD $wpdb
410 *
411 * @since 1.0.0
412 *
413 * @return string
414 */
415 public function orderby() {
416 global $wpdb;
417
418 /**
419 * Filter the `ORDER BY` statement.
420 *
421 * @since 1.0.0
422 *
423 * @param string $sql The `ORDER BY` statement.
424 * @param Charitable_Query $query The `Charitable_Query` instance.
425 */
426 return apply_filters( 'charitable_query_orderby', "ORDER BY {$wpdb->posts}.ID", $this );
427 }
428
429 /**
430 * Return the ORDER part of the query.
431 *
432 * @since 1.0.0
433 *
434 * @return string
435 */
436 public function order() {
437 /**
438 * Filter the `ORDER` statement.
439 *
440 * @since 1.0.0
441 *
442 * @param string $sql The `ORDER` statement. DESC by default.
443 * @param Charitable_Query $query The `Charitable_Query` instance.
444 */
445 return apply_filters( 'charitable_query_order', $this->get( 'order', 'DESC' ), $this );
446 }
447
448 /**
449 * Return the LIMIT part of the query.
450 *
451 * @since 1.0.0
452 *
453 * @return string
454 */
455 public function limit() {
456 if ( $this->show_all() ) {
457 return '';
458 }
459
460 /**
461 * Filter the `LIMIT` statement.
462 *
463 * @since 1.0.0
464 *
465 * @param string $sql The `LIMIT` statement.
466 * @param Charitable_Query $query The `Charitable_Query` instance.
467 */
468 return apply_filters( 'charitable_query_limit', sprintf( 'LIMIT %d', $this->get( 'number', 20 ) ), $this );
469 }
470
471 /**
472 * Return the OFFSET part of the query.
473 *
474 * @since 1.0.0
475 *
476 * @return string
477 */
478 public function offset() {
479 if ( $this->show_all() ) {
480 return '';
481 }
482
483 $offset = $this->get( 'number' ) * ( $this->get( 'paged', 1 ) - 1 );
484
485 /**
486 * Filter the `OFFSET` statement.
487 *
488 * @since 1.0.0
489 *
490 * @param string $sql The `OFFSET` statement.
491 * @param Charitable_Query $query The `Charitable_Query` instance.
492 */
493 return apply_filters( 'charitable_query_offset', sprintf( 'OFFSET %d', $offset ), $this );
494 }
495
496 /**
497 * Select donor-specific fields.
498 *
499 * @since 1.0.0
500 *
501 * @param string $select_statement The default select statement.
502 * @return string
503 */
504 public function donor_fields( $select_statement ) {
505 return $select_statement . ', d.donor_id, d.user_id, d.first_name, d.last_name, d.email, d.date_joined';
506 }
507
508 /**
509 * Retrieve the donation ID and campaigns.
510 *
511 * @since 1.0.0
512 *
513 * @param string $select_statement The default select statement.
514 * @return string
515 */
516 public function donation_fields( $select_statement ) {
517 return $select_statement . ", cd.donation_id, GROUP_CONCAT(cd.campaign_name SEPARATOR ', ') AS campaigns, GROUP_CONCAT(cd.campaign_id SEPARATOR ',') AS campaign_ids, cd.donor_id";
518 }
519
520 /**
521 * Select donation-specific fields.
522 *
523 * @since 1.0.0
524 *
525 * @param string $select_statement The default select statement.
526 * @return string
527 */
528 public function donation_calc_fields( $select_statement ) {
529 return $select_statement . ', COUNT(cd.campaign_donation_id) AS donations, SUM(cd.amount) AS amount';
530 }
531
532 /**
533 * Select total amount field.
534 *
535 * @since 1.2.0
536 *
537 * @param string $select_statement The default select statement.
538 * @return string
539 */
540 public function donation_amount_sum_field( $select_statement ) {
541 return $select_statement . ', SUM(cd.amount) AS amount';
542 }
543
544 /**
545 * Return the SQL to be used for meta queries.
546 *
547 * @since 1.6.5
548 *
549 * @global WPDB $wpdb
550 *
551 * @return false|array {
552 * Array containing JOIN and WHERE SQL clauses to append to the main query.
553 *
554 * @type string $join SQL fragment to append to the main JOIN clause.
555 * @type string $where SQL fragment to append to the main WHERE clause.
556 * }
557 */
558 public function get_meta_sql() {
559 if ( ! isset( $this->meta_sql ) ) {
560 global $wpdb;
561
562 $meta_args = $this->get( 'meta_query' );
563
564 if ( empty( $meta_args ) ) {
565 return false;
566 }
567
568 $meta_query = new WP_Meta_Query( $meta_args );
569
570 $this->meta_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' );
571 }
572
573 return $this->meta_sql;
574 }
575
576 /**
577 * A helper function used to populate the query parameters ith an item and a return a string
578 * of placeholders that can be used in a MySQL `IN` statement.
579 *
580 * @since 1.5.0
581 *
582 * @param mixed $item The item.
583 * @param callable $filter_callback A callback to use to filter out invalid items.
584 * @param string $placeholder_type The type of placeholder to use. May be %s, %d or %f.
585 * @return string A string containing the correct number of placeholders.
586 */
587 public function get_where_in_placeholders( $item, $filter_callback, $placeholder_type ) {
588 if ( ! is_array( $item ) ) {
589 $item = array( $item );
590 }
591
592 $item = array_filter( $item, $filter_callback );
593
594 $this->add_parameters( $item );
595
596 return $this->get_placeholders( count( $item ), $placeholder_type );
597 }
598
599 /**
600 * Filter query by donation_plan ID.
601 *
602 * @since 1.6.8
603 *
604 * @global WPBD $wpdb
605 * @param string $where_statement The default where statement.
606 * @return string
607 */
608 public function where_donation_plan_is_in( $where_statement ) {
609 global $wpdb;
610
611 $donation_plan = $this->get( 'donation_plan', false );
612
613 if ( ! $donation_plan ) {
614 return $where_statement;
615 }
616
617 $placeholders = $this->get_where_in_placeholders( $donation_plan, 'charitable_validate_absint', '%d' );
618
619 return $where_statement . " AND {$wpdb->posts}.post_parent IN ({$placeholders})";
620 }
621
622 /**
623 * Filter query by campaign receiving the donation.
624 *
625 * @since 1.0.0
626 *
627 * @param string $where_statement The default where statement.
628 * @return string
629 */
630 public function where_campaign_is_in( $where_statement ) {
631 $campaign = $this->get( 'campaign', 0 );
632
633 if ( ! $campaign ) {
634 return $where_statement;
635 }
636
637 $placeholders = $this->get_where_in_placeholders( $this->get( 'campaign', 0 ), 'charitable_validate_absint', '%d' );
638
639 return $where_statement . " AND cd.campaign_id IN ({$placeholders})";
640 }
641
642 /**
643 * Filter query by status of the post.
644 *
645 * @global WPBD $wpdb
646 *
647 * @since 1.0.0
648 *
649 * @param string $where_statement The default where statement.
650 * @return string
651 */
652 public function where_status_is_in( $where_statement ) {
653 global $wpdb;
654
655 $status = $this->get( 'status', false );
656
657 if ( ! $status ) {
658 return $where_statement;
659 }
660
661 $placeholders = $this->get_where_in_placeholders( $status, 'charitable_is_valid_donation_status', '%s' );
662
663 return $where_statement . " AND {$wpdb->posts}.post_status IN ({$placeholders})";
664 }
665
666 /**
667 * Filter query by donor ID.
668 *
669 * @global WPBD $wpdb
670 * @since 1.0.0
671 * @version 1.7.0.9
672 *
673 * @param string $where_statement The default where statement.
674 * @return string
675 */
676 public function where_donor_id_is_in( $where_statement ) {
677
678 $donor_email_passed = isset( $_GET['donor_email'] ) ? esc_html( $_GET['donor_email' ] ) : false;
679 $donor_email = $this->get( 'email', $donor_email_passed );
680
681 if ( $donor_email ) { // stop searching by ID, we will search by email that was supplied.
682 return $where_statement;
683 }
684
685 $donor_id = $this->get( 'donor_id', false );
686
687 if ( ! $donor_id ) {
688 return $where_statement;
689 }
690
691 $placeholders = $this->get_where_in_placeholders( $donor_id, 'charitable_validate_absint', '%d' );
692
693 return $where_statement . " AND cd.donor_id IN ({$placeholders})";
694 }
695
696 /**
697 * Filter query by donor email.
698 *
699 * @global WPBD $wpdb
700 * @since 1.7.0.9
701 *
702 * @param string $where_statement The default where statement.
703 * @return string
704 */
705 public function where_donor_email_is_in( $where_statement ) {
706 return $where_statement;
707 }
708
709 /**
710 * Filter query by user ID.
711 *
712 * @since 1.5.0
713 *
714 * @global WPBD $wpdb
715 * @param string $where_statement The default where statement.
716 * @return string
717 */
718 public function where_user_id_is_in( $where_statement ) {
719 global $wpdb;
720
721 $user_id = $this->get( 'user_id', false );
722
723 if ( ! $user_id ) {
724 return $where_statement;
725 }
726
727 $placeholders = $this->get_where_in_placeholders( $user_id, 'charitable_validate_absint', '%d' );
728
729 return $where_statement . " AND {$wpdb->posts}.post_author IN ({$placeholders})";
730 }
731
732 /**
733 * Filter query by donation ID(s).
734 *
735 * @since 1.7.0.9
736 *
737 * @global WPBD $wpdb
738 * @param string $where_statement The default where statement.
739 * @return string
740 */
741 public function where_donation_id_is_in( $where_statement ) {
742 global $wpdb;
743
744 $donation_ids_passed = isset( $_GET['donation_ids'] ) ? esc_html( $_GET['donation_ids' ] ) : false;
745
746 if ( $donation_ids_passed === false ) {
747 return $where_statement;
748 }
749
750 // this could be a comma delimited list.
751 $donation_ids = explode( ',', $donation_ids_passed );
752
753 if ( empty( $donation_ids ) ) {
754 return $where_statement;
755 }
756
757 return $where_statement . " AND {$wpdb->posts}.ID IN ({$donation_ids_passed})";
758 }
759
760 /**
761 * Filter a query by date.
762 *
763 * @uses WP_Date_Query
764 *
765 * @since 1.5.0
766 *
767 * @param string $where_statement The where query.
768 * @return string
769 */
770 public function where_date( $where_statement ) {
771 $date_args = $this->get( 'date_query' );
772
773 if ( empty( $date_args ) ) {
774 return $where_statement;
775 }
776
777 $date_query = new WP_Date_Query( $date_args );
778
779 return $where_statement . $date_query->get_sql();
780 }
781
782 /**
783 * Filter a query by meta data.
784 *
785 * @uses WP_Meta_Query
786 *
787 * @since 1.6.5
788 *
789 * @param string $where_statement The where query.
790 * @return string
791 */
792 public function where_meta( $where_statement ) {
793 $meta_sql = $this->get_meta_sql();
794
795 if ( ! $meta_sql || empty( $meta_sql['where'] ) ) {
796 return $where_statement;
797 }
798
799 return $where_statement . $meta_sql['where'];
800 }
801
802 /**
803 * A method used to join the campaign donations table on the campaigns query.
804 *
805 * @global WPBD $wpdb
806 *
807 * @since 1.0.0
808 *
809 * @param string $join_statement The default join statement.
810 * @return string
811 */
812 public function join_campaign_donations_table_on_campaign( $join_statement ) {
813 global $wpdb;
814 return $join_statement . " INNER JOIN {$wpdb->prefix}charitable_campaign_donations cd ON cd.campaign_id = $wpdb->posts.ID ";
815 }
816
817 /**
818 * Add one or more joins to the post meta table.
819 *
820 * @uses WP_Meta_Query
821 *
822 * @since 1.6.5
823 *
824 * @param string $join_statement The where query.
825 * @return string
826 */
827 public function join_meta( $join_statement ) {
828 $meta_sql = $this->get_meta_sql();
829
830 if ( ! $meta_sql || empty( $meta_sql['join'] ) ) {
831 return $join_statement;
832 }
833
834 return $join_statement . $meta_sql['join'];
835 }
836
837 /**
838 * A method used to join the campaign donations table on the campaigns query.
839 *
840 * @global WPBD $wpdb
841 *
842 * @since 1.0.0
843 *
844 * @param string $join_statement The default join statement.
845 * @return string
846 */
847 public function join_campaign_donations_table_on_donation( $join_statement ) {
848 global $wpdb;
849 return $join_statement . " INNER JOIN {$wpdb->prefix}charitable_campaign_donations cd ON cd.donation_id = $wpdb->posts.ID ";
850 }
851
852 /**
853 * A method used to join the campaign donations table on the campaigns query.
854 *
855 * @global WPBD $wpdb
856 *
857 * @since 1.7.0.9
858 *
859 * @param string $join_statement The default join statement.
860 * @return string
861 */
862 public function join_campaign_donors_table_on_donation( $join_statement ) {
863 global $wpdb;
864 return $join_statement . " INNER JOIN {$wpdb->prefix}charitable_donors cdn ON cdn.donor_id = cd.donor_id ";
865 }
866
867 /**
868 * A method used to join the donors table on the query.
869 *
870 * @global WPBD $wpdb
871 * @since 1.5.0
872 *
873 * @param string $join_statement The default join statement.
874 * @return string
875 */
876 public function join_post_meta_table_on_donation( $join_statement ) {
877 global $wpdb;
878 return $join_statement . " INNER JOIN $wpdb->postmeta pm ON pm.post_id = $wpdb->posts.ID ";
879 }
880
881 /**
882 * A method used to join the donors table on the query.
883 *
884 * @global WPBD $wpdb
885 * @since 1.0.0
886 *
887 * @param string $join_statement The default join statement.
888 * @return string
889 */
890 public function join_donors_table( $join_statement ) {
891 global $wpdb;
892 return $join_statement . " INNER JOIN {$wpdb->prefix}charitable_donors d ON d.donor_id = cd.donor_id ";
893 }
894
895 /**
896 * Group results by the ID.
897 *
898 * @global WPBD $wpdb
899 * @since 1.0.0
900 *
901 * @return string
902 */
903 public function groupby_ID() {
904 global $wpdb;
905 return "GROUP BY {$wpdb->posts}.ID";
906 }
907
908 /**
909 * Group a query by the donor ID.
910 *
911 * @since 1.0.0
912 *
913 * @return string
914 */
915 public function groupby_donor_id() {
916 return 'GROUP BY cd.donor_id';
917 }
918
919 /**
920 * Group a query by the donation ID.
921 *
922 * @since 1.4.0
923 *
924 * @return string
925 */
926 public function groupby_donation_id() {
927 return 'GROUP BY cd.donation_id';
928 }
929
930 /**
931 * Order by the date of the post.
932 *
933 * @global WPBD $wpdb
934 * @since 1.0.0
935 *
936 * @return string
937 */
938 public function orderby_date() {
939 global $wpdb;
940 return "ORDER BY {$wpdb->posts}.post_date";
941 }
942
943 /**
944 * Order by the results count of the ID column.
945 *
946 * This is useful when used in combination with a group statement.
947 *
948 * @since 1.0.0
949 *
950 * @return string
951 */
952 public function orderby_count() {
953 return 'ORDER BY COUNT(*)';
954 }
955
956 /**
957 * A method used to change the ordering of the campaigns query, to order by the amount donated.
958 *
959 * @since 1.0.0
960 *
961 * @return string
962 */
963 public function orderby_donation_amount() {
964 return 'ORDER BY COALESCE(SUM(cd.amount), 0)';
965 }
966
967 /**
968 * Return number of results.
969 *
970 * @since 1.0.0
971 *
972 * @return int
973 */
974 public function count() {
975 return 'count' == $this->get( 'output' ) ? $this->found_items : count( $this->results );
976 }
977
978 /**
979 * Return total result count.
980 *
981 * @since 1.5.0
982 *
983 * @return int
984 */
985 public function found_items() {
986 return $this->found_items;
987 }
988
989 /**
990 * Rewind to first result.
991 *
992 * @since 1.0.0
993 *
994 * @return void
995 */
996 #[\ReturnTypeWillChange]
997 public function rewind() {
998 $this->position = 0;
999 }
1000
1001 /**
1002 * Return current element.
1003 *
1004 * @since 1.0.0
1005 *
1006 * @return object
1007 */
1008 #[\ReturnTypeWillChange]
1009 public function current() {
1010 return $this->results[ $this->position ];
1011 }
1012
1013 /**
1014 * Return current key.
1015 *
1016 * @since 1.0.0
1017 *
1018 * @return int
1019 */
1020 #[\ReturnTypeWillChange]
1021 public function key() {
1022 return $this->position;
1023 }
1024
1025 /**
1026 * Advance to next item.
1027 *
1028 * @since 1.0.0
1029 *
1030 * @return void
1031 */
1032 #[\ReturnTypeWillChange]
1033 public function next() {
1034 ++$this->position;
1035 }
1036
1037 /**
1038 * Ensure that current position is valid.
1039 *
1040 * @since 1.0.0
1041 *
1042 * @return boolean
1043 */
1044 #[\ReturnTypeWillChange]
1045 public function valid() {
1046 return isset( $this->results[ $this->position ] );
1047 }
1048
1049 /**
1050 * Add parameters to pass to the prepared query.
1051 *
1052 * @since 1.0.0
1053 *
1054 * @param mixed $parameters Parameters to be set for the query.
1055 * @return void
1056 */
1057 public function add_parameters( $parameters ) {
1058 $this->parameters = array_merge( $this->parameters, $parameters );
1059 }
1060
1061 /**
1062 * Whether to show all results.
1063 *
1064 * @since 1.1.0
1065 *
1066 * @return boolean
1067 */
1068 public function show_all() {
1069 return -1 == $this->get( 'number' );
1070 }
1071
1072 /**
1073 * Return the correct number of placeholders given a symbol and count.
1074 *
1075 * @since 1.0.0
1076 *
1077 * @param int $count Number of placeholders.
1078 * @param string $placeholder Placeholder symbol.
1079 * @return string
1080 */
1081 protected function get_placeholders( $count = 1, $placeholder = '%s' ) {
1082 return charitable_get_query_placeholders( $count, $placeholder );
1083 }
1084 }
1085
1086 endif;
1087