PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.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
← All changes | includes/abstracts/abstract-class-charitable-query.php +108 -8 1.7.0.3 → 1.8.13 View file →
@@ -3,9 +3,9 @@
3 3 * An abstract base class defining common methods used by Charitable queries.
4 4 *
5 5 * @package Charitable/Classes/Charitable_Query
6 6 * @author David Bisset
7 - * @copyright Copyright (c) 2022, WP Charitable LLC
7 + * @copyright Copyright (c) 2023, WP Charitable LLC
8 8 * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 9 * @since 1.0.0
10 10 * @version 1.6.8
11 11 */
@@ -192,9 +192,9 @@
192 192 global $wpdb;
193 193
194 194 $sql = "SELECT {$this->fields()} {$this->from()} {$this->join()} {$this->where()} {$this->groupby()} {$this->orderby()} {$this->order()} {$this->limit()} {$this->offset()};";
195 195
196 - return $wpdb->get_results( $this->get_prepared_sql( $sql ) );
196 + return $wpdb->get_results( $this->get_prepared_sql( $sql ) ); // phpcs:ignore
197 197 }
198 198
199 199 /**
200 200 * Run count query, returning the results.
@@ -209,9 +209,9 @@
209 209 global $wpdb;
210 210
211 211 $sql = "SELECT {$this->select_count()} {$this->from()} {$this->join()} {$this->where()};";
212 212
213 - return array( $wpdb->get_var( $this->get_prepared_sql( $sql ) ) );
213 + return array( $wpdb->get_var( $this->get_prepared_sql( $sql ) ) ); // phpcs:ignore
214 214 }
215 215
216 216 /**
217 217 * Prepare a query with any passed parameters.
@@ -229,9 +229,9 @@
229 229 if ( empty( $this->parameters ) ) {
230 230 return $sql;
231 231 }
232 232
233 - return $wpdb->prepare( $sql, $this->parameters );
233 + return $wpdb->prepare( $sql, $this->parameters ); // phpcs:ignore
234 234 }
235 235
236 236 /**
237 237 * After a query has been executed, check how many found rows there are.
@@ -266,9 +266,9 @@
266 266 * @param Charitable_Query $query The `Charitable_Query` instance.
267 267 */
268 268 $found_items_query = apply_filters( 'charitable_found_items_query', 'SELECT FOUND_ROWS()', $this );
269 269
270 - return (int) $wpdb->get_var( $found_items_query );
270 + return (int) $wpdb->get_var( $found_items_query ); // phpcs:ignore
271 271 }
272 272
273 273 /**
274 274 * Return the count query right after the SELECT part of the query.
@@ -426,10 +426,18 @@
426 426
427 427 /**
428 428 * Return the ORDER part of the query.
429 429 *
430 - * @since 1.0.0
430 + * The returned value is interpolated directly into the SQL statement
431 + * assembled by Charitable_Query::run_query(). A sort direction cannot be
432 + * passed to $wpdb->prepare() as a placeholder, so it is validated against
433 + * a strict whitelist here instead. Any value other than ASC or DESC --
434 + * including anything supplied through a shortcode attribute or the
435 + * `charitable_query_order` filter -- falls back to DESC.
431 436 *
437 + * @since 1.0.0
438 + * @version 1.8.12.2
439 + *
432 440 * @return string
433 441 */
434 442 public function order() {
435 443 /**
@@ -434,14 +442,19 @@
434 442 public function order() {
435 443 /**
436 444 * Filter the `ORDER` statement.
437 445 *
446 + * Note that the filtered value is validated against ASC/DESC before it
447 + * is used in the query, so returning any other value has no effect.
448 + *
438 449 * @since 1.0.0
439 450 *
440 451 * @param string $sql The `ORDER` statement. DESC by default.
441 452 * @param Charitable_Query $query The `Charitable_Query` instance.
442 453 */
443 - return apply_filters( 'charitable_query_order', $this->get( 'order', 'DESC' ), $this );
454 + $order = apply_filters( 'charitable_query_order', $this->get( 'order', 'DESC' ), $this );
455 +
456 + return charitable_validate_sort_direction( $order );
444 457 }
445 458
446 459 /**
447 460 * Return the LIMIT part of the query.
@@ -665,13 +678,22 @@
665 678 * Filter query by donor ID.
666 679 *
667 680 * @global WPBD $wpdb
668 681 * @since 1.0.0
682 + * @version 1.7.0.9
669 683 *
670 684 * @param string $where_statement The default where statement.
671 685 * @return string
672 686 */
673 687 public function where_donor_id_is_in( $where_statement ) {
688 +
689 + $donor_email_passed = isset( $_GET['donor_email'] ) ? sanitize_email( $_GET['donor_email'] ) : false; // phpcs:ignore
690 + $donor_email = $this->get( 'email', $donor_email_passed );
691 +
692 + if ( $donor_email ) { // stop searching by ID, we will search by email that was supplied.
693 + return $where_statement;
694 + }
695 +
674 696 $donor_id = $this->get( 'donor_id', false );
675 697
676 698 if ( ! $donor_id ) {
677 699 return $where_statement;
@@ -682,8 +704,21 @@
682 704 return $where_statement . " AND cd.donor_id IN ({$placeholders})";
683 705 }
684 706
685 707 /**
708 + * Filter query by donor email.
709 + *
710 + * @global WPBD $wpdb
711 + * @since 1.7.0.9
712 + *
713 + * @param string $where_statement The default where statement.
714 + * @return string
715 + */
716 + public function where_donor_email_is_in( $where_statement ) {
717 + return $where_statement;
718 + }
719 +
720 + /**
686 721 * Filter query by user ID.
687 722 *
688 723 * @since 1.5.0
689 724 *
@@ -705,8 +740,53 @@
705 740 return $where_statement . " AND {$wpdb->posts}.post_author IN ({$placeholders})";
706 741 }
707 742
708 743 /**
744 + * Filter query by donation ID(s).
745 + *
746 + * @since 1.7.0.9
747 + * @version 1.8.8.5
748 + *
749 + * @global WPBD $wpdb
750 + * @param string $where_statement The default where statement.
751 + * @return string
752 + */
753 + public function where_donation_id_is_in( $where_statement ) {
754 + global $wpdb;
755 +
756 + $donation_ids_passed = isset( $_GET['donation_ids'] ) ? sanitize_text_field( $_GET['donation_ids'] ) : false; // phpcs:ignore
757 +
758 + if ( $donation_ids_passed === false ) {
759 + return $where_statement;
760 + }
761 +
762 + // this could be a comma delimited list.
763 + $donation_ids = explode( ',', $donation_ids_passed );
764 +
765 + if ( empty( $donation_ids ) ) {
766 + return $where_statement;
767 + }
768 +
769 + // Validate and sanitize each donation ID to ensure they are positive integers
770 + $valid_donation_ids = array();
771 + foreach ( $donation_ids as $donation_id ) {
772 + $donation_id = trim( $donation_id );
773 + if ( is_numeric( $donation_id ) && intval( $donation_id ) > 0 ) {
774 + $valid_donation_ids[] = intval( $donation_id );
775 + }
776 + }
777 +
778 + if ( empty( $valid_donation_ids ) ) {
779 + return $where_statement;
780 + }
781 +
782 + // Use proper parameterized query with placeholders
783 + $placeholders = $this->get_where_in_placeholders( $valid_donation_ids, 'charitable_validate_absint', '%d' );
784 +
785 + return $where_statement . " AND {$wpdb->posts}.ID IN ({$placeholders})";
786 + }
787 +
788 + /**
709 789 * Filter a query by date.
710 790 *
711 791 * @uses WP_Date_Query
712 792 *
@@ -797,8 +877,23 @@
797 877 return $join_statement . " INNER JOIN {$wpdb->prefix}charitable_campaign_donations cd ON cd.donation_id = $wpdb->posts.ID ";
798 878 }
799 879
800 880 /**
881 + * A method used to join the campaign donations table on the campaigns query.
882 + *
883 + * @global WPBD $wpdb
884 + *
885 + * @since 1.7.0.9
886 + *
887 + * @param string $join_statement The default join statement.
888 + * @return string
889 + */
890 + public function join_campaign_donors_table_on_donation( $join_statement ) {
891 + global $wpdb;
892 + return $join_statement . " INNER JOIN {$wpdb->prefix}charitable_donors cdn ON cdn.donor_id = cd.donor_id ";
893 + }
894 +
895 + /**
801 896 * A method used to join the donors table on the query.
802 897 *
803 898 * @global WPBD $wpdb
804 899 * @since 1.5.0
@@ -925,8 +1020,9 @@
925 1020 * @since 1.0.0
926 1021 *
927 1022 * @return void
928 1023 */
1024 + #[\ReturnTypeWillChange]
929 1025 public function rewind() {
930 1026 $this->position = 0;
931 1027 }
932 1028
@@ -936,10 +1032,11 @@
936 1032 * @since 1.0.0
937 1033 *
938 1034 * @return object
939 1035 */
1036 + #[\ReturnTypeWillChange]
940 1037 public function current() {
941 - return $this->results[ $this->position ];
1038 + return isset( $this->results[ $this->position ] ) ? $this->results[ $this->position ] : false;
942 1039 }
943 1040
944 1041 /**
945 1042 * Return current key.
@@ -947,8 +1044,9 @@
947 1044 * @since 1.0.0
948 1045 *
949 1046 * @return int
950 1047 */
1048 + #[\ReturnTypeWillChange]
951 1049 public function key() {
952 1050 return $this->position;
953 1051 }
954 1052
@@ -958,8 +1056,9 @@
958 1056 * @since 1.0.0
959 1057 *
960 1058 * @return void
961 1059 */
1060 + #[\ReturnTypeWillChange]
962 1061 public function next() {
963 1062 ++$this->position;
964 1063 }
965 1064
@@ -969,8 +1068,9 @@
969 1068 * @since 1.0.0
970 1069 *
971 1070 * @return boolean
972 1071 */
1072 + #[\ReturnTypeWillChange]
973 1073 public function valid() {
974 1074 return isset( $this->results[ $this->position ] );
975 1075 }
976 1076