PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.17.0
GiveWP – Donation Plugin and Fundraising Platform v4.17.0
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 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 All 256 releases
← All changes | includes/donors/class-give-donors-query.php +159 -44 2.3.2 → 4.17.0 View file →
@@ -32,9 +32,9 @@
32 32 * @access public
33 33 *
34 34 * @var array
35 35 */
36 - public $args = array();
36 + public $args = [];
37 37
38 38 /**
39 39 * The donors found based on the criteria set
40 40 *
@@ -42,9 +42,9 @@
42 42 * @access public
43 43 *
44 44 * @var array
45 45 */
46 - public $donors = array();
46 + public $donors = [];
47 47
48 48 /**
49 49 * The donors found based on the criteria set
50 50 *
@@ -75,8 +75,18 @@
75 75 */
76 76 public $meta_type = '';
77 77
78 78 /**
79 + * Preserve args
80 + *
81 + * @since 2.4.0
82 + * @access public
83 + *
84 + * @var array
85 + */
86 + public $_args = [];
87 +
88 + /**
79 89 * Default query arguments.
80 90 *
81 91 * Not all of these are valid arguments that can be passed to WP_Query. The ones that are not, are modified before
82 92 * the query is run to convert them to the proper syntax.
@@ -85,10 +95,10 @@
85 95 * @access public
86 96 *
87 97 * @param $args array The array of arguments that can be passed in and used for setting up this payment query.
88 98 */
89 - public function __construct( $args = array() ) {
90 - $defaults = array(
99 + public function __construct( $args = [] ) {
100 + $defaults = [
91 101 'number' => 20,
92 102 'offset' => 0,
93 103 'paged' => 1,
94 104 'orderby' => 'id',
@@ -95,14 +105,16 @@
95 105 'order' => 'DESC',
96 106 'user' => null,
97 107 'email' => null,
98 108 'donor' => null,
99 - 'meta_query' => array(),
100 - 'date_query' => array(),
109 + 'meta_query' => [],
110 + 'date_query' => [],
101 111 's' => null,
102 112 'fields' => 'all', // Supports donors (all fields) or valid column as string or array list.
103 113 'count' => false,
104 - 'give_forms' => array(),
114 + 'give_forms' => [],
115 + 'start_date' => false,
116 + 'end_date' => false,
105 117
106 118 /**
107 119 * donation_amount will contain value like:
108 120 * array(
@@ -111,16 +123,17 @@
111 123 * )
112 124 *
113 125 * You can also pass number value to this param then compare symbol will auto set to >
114 126 */
115 - 'donation_amount' => array()
116 - // 'form' => array(),
117 - );
127 + 'donation_amount' => [],
128 + ];
118 129
119 - $this->args = wp_parse_args( $args, $defaults );
130 + $this->args = $this->_args = wp_parse_args( $args, $defaults );
120 131 $this->table_name = Give()->donors->table_name;
121 132 $this->meta_table_name = Give()->donor_meta->table_name;
122 133 $this->meta_type = Give()->donor_meta->meta_type;
134 +
135 + $this->date_filter_pre();
123 136 }
124 137
125 138 /**
126 139 * Modify the query/query arguments before we retrieve donors.
@@ -145,9 +158,9 @@
145 158 * @access public
146 159 *
147 160 * @global wpdb $wpdb
148 161 *
149 - * @return array
162 + * @return array|object|string|null
150 163 */
151 164 public function get_donors() {
152 165 global $wpdb;
153 166
@@ -164,11 +177,12 @@
164 177
165 178 // Get donors from cache.
166 179 $this->donors = Give_Cache::get_db_query( $cache_key );
167 180
168 - if ( is_null( $this->donors ) ) {
181 + if ( null === $this->donors ) {
169 182 if ( empty( $this->args['count'] ) ) {
170 183 $this->donors = $wpdb->get_results( $this->get_sql() );
184 + self::update_meta_cache( wp_list_pluck( (array) $this->donors, 'id' ) );
171 185 } else {
172 186 $this->donors = $wpdb->get_var( $this->get_sql() );
173 187 }
174 188
@@ -174,9 +188,8 @@
174 188
175 189 Give_Cache::set_db_query( $cache_key, $this->donors );
176 190 }
177 191
178 -
179 192 /**
180 193 * Fires after retrieving donors.
181 194 *
182 195 * @since 1.8.14
@@ -205,9 +218,8 @@
205 218 }
206 219
207 220 $where = $this->get_where_query();
208 221
209 -
210 222 // Set offset.
211 223 if ( empty( $this->args['offset'] ) && ( 0 < $this->args['paged'] ) ) {
212 224 $this->args['offset'] = $this->args['number'] * ( $this->args['paged'] - 1 );
213 225 }
@@ -344,17 +356,21 @@
344 356 // Donors created for a specific date or in a date range
345 357 if ( ! empty( $this->args['date_query'] ) ) {
346 358 $date_query_object = new WP_Date_Query( is_array( $this->args['date_query'] ) ? $this->args['date_query'] : wp_parse_args( $this->args['date_query'] ), "{$this->table_name}.date_created" );
347 359
348 - $where .= str_replace( array(
349 - "\n",
350 - '( (',
351 - '))',
352 - ), array(
353 - '',
354 - '( (',
355 - ') )',
356 - ), $date_query_object->get_sql() );
360 + $where .= str_replace(
361 + [
362 + "\n",
363 + '( (',
364 + '))',
365 + ],
366 + [
367 + '',
368 + '( (',
369 + ') )',
370 + ],
371 + $date_query_object->get_sql()
372 + );
357 373 }
358 374
359 375 return $where;
360 376 }
@@ -370,23 +386,33 @@
370 386 */
371 387 private function get_where_search() {
372 388 $where = '';
373 389
390 + // Bailout.
391 + if ( empty( $this->args['s'] ) ) {
392 + return $where;
393 + }
394 +
374 395 // Donors created for a specific date or in a date range
375 - if ( ! empty( $this->args['s'] ) && false !== strpos( $this->args['s'], ':' ) ) {
396 + if ( false !== strpos( $this->args['s'], ':' ) ) {
376 397 $search_parts = explode( ':', $this->args['s'] );
377 -
378 398 if ( ! empty( $search_parts[0] ) ) {
379 399 switch ( $search_parts[0] ) {
400 + // Backward compatibility.
380 401 case 'name':
381 402 $where = "AND {$this->table_name}.name LIKE '%{$search_parts[1]}%'";
382 403 break;
383 -
384 404 case 'note':
385 405 $where = "AND {$this->table_name}.notes LIKE '%{$search_parts[1]}%'";
386 406 break;
387 407 }
388 408 }
409 + } elseif ( is_numeric( $this->args['s'] ) ) {
410 + $where = "AND {$this->table_name}.id ='{$this->args['s']}'";
411 +
412 + } else {
413 + $search_field = is_email( $this->args['s'] ) ? 'email' : 'name';
414 + $where = "AND {$this->table_name}.$search_field LIKE '%{$this->args['s']}%'";
389 415 }
390 416
391 417 return $where;
392 418 }
@@ -426,43 +452,49 @@
426 452 */
427 453 private function get_order_query() {
428 454 $table_columns = Give()->donors->get_columns();
429 455
430 - $query = array();
456 + $query = [];
431 457 $ordersby = $this->args['orderby'];
432 458
433 - if( ! is_array( $ordersby ) ) {
434 - $ordersby = array(
435 - $this->args['orderby'] => $this->args['order']
436 - );
459 + if ( ! is_array( $ordersby ) ) {
460 + $ordersby = [
461 + $this->args['orderby'] => $this->args['order'],
462 + ];
437 463 }
438 464
439 465 // Remove non existing column.
440 466 // Filter orderby values.
441 467 foreach ( $ordersby as $orderby => $order ) {
442 - if( ! array_key_exists( $orderby, $table_columns ) ) {
443 - unset( $ordersby[$orderby] );
468 + if ( ! array_key_exists( $orderby, $table_columns ) ) {
469 + unset( $ordersby[ $orderby ] );
470 + continue;
444 471 }
445 472
446 473 $ordersby[ esc_sql( $orderby ) ] = esc_sql( $order );
447 474 }
448 475
449 - if( empty( $ordersby ) ) {
450 - $ordersby = array(
451 - 'id' => $this->args['order']
452 - );
476 + if ( empty( $ordersby ) ) {
477 + $ordersby = [
478 + 'id' => $this->args['order'],
479 + ];
453 480 }
454 481
455 482 // Create query.
456 483 foreach ( $ordersby as $orderby => $order ) {
484 + /**
485 + * @since 3.16.2 Prevent SQL Injection by not using the user defined order value directly in the query.
486 + */
487 + $sanitizedOrder = $order === 'ASC' ? 'ASC' : 'DESC';
488 +
457 489 switch ( $table_columns[ $orderby ] ) {
458 490 case '%d':
459 491 case '%f':
460 - $query[] = "{$this->table_name}.{$orderby}+0 {$order}";
492 + $query[] = "{$this->table_name}.{$orderby}+0 {$sanitizedOrder}";
461 493 break;
462 494
463 495 default:
464 - $query[] = "{$this->table_name}.{$orderby} {$order}";
496 + $query[] = "{$this->table_name}.{$orderby} {$sanitizedOrder}";
465 497 }
466 498 }
467 499
468 500 return ! empty( $query ) ? 'ORDER BY ' . implode( ', ', $query ) : '';
@@ -469,8 +501,9 @@
469 501 }
470 502
471 503 /**
472 504 * Set donation count value where clause.
505 + *
473 506 * @todo: add phpunit test
474 507 *
475 508 * @since 2.2.0
476 509 * @access private
@@ -485,9 +518,9 @@
485 518 $compare = '>';
486 519 $amount = $this->args['donation_count'];
487 520 if ( is_array( $this->args['donation_count'] ) ) {
488 521 $compare = $this->args['donation_count'] ['compare'];
489 - $amount = $this->args['donation_count']['amount'];
522 + $amount = $this->args['donation_count']['amount'];
490 523 }
491 524
492 525 $where .= "AND {$this->table_name}.purchase_count{$compare}{$amount}";
493 526 }
@@ -496,8 +529,9 @@
496 529 }
497 530
498 531 /**
499 532 * Set purchase value where clause.
533 + *
500 534 * @todo: add phpunit test
501 535 *
502 536 * @since 2.1.0
503 537 * @access private
@@ -512,9 +546,9 @@
512 546 $compare = '>';
513 547 $amount = $this->args['donation_amount'];
514 548 if ( is_array( $this->args['donation_amount'] ) ) {
515 549 $compare = $this->args['donation_amount'] ['compare'];
516 - $amount = $this->args['donation_amount']['amount'];
550 + $amount = $this->args['donation_amount']['amount'];
517 551 }
518 552
519 553 $where .= "AND {$this->table_name}.purchase_value{$compare}{$amount}";
520 554 }
@@ -526,9 +560,11 @@
526 560 * Set give_forms where clause.
527 561 *
528 562 * @todo : add phpunit test
529 563 *
564 + * @since 4.14.0 Replace {$wpdb->paymentmeta} with {$wpdb->donationmeta}
530 565 * @since 2.1.0
566 + *
531 567 * @access private
532 568 *
533 569 * @global wpdb $wpdb
534 570 * @return string
@@ -551,9 +587,9 @@
551 587 FROM {$wpdb->donationmeta}
552 588 WHERE meta_key=%s
553 589 AND {$donation_id_col} IN(
554 590 SELECT {$donation_id_col}
555 - FROM {$wpdb->paymentmeta}
591 + FROM {$wpdb->donationmeta}
556 592 WHERE meta_key=%s
557 593 AND meta_value IN (%s)
558 594 )
559 595 ",
@@ -566,9 +602,9 @@
566 602
567 603 if ( ! empty( $donor_ids ) ) {
568 604 $donor_ids = wp_list_pluck( $donor_ids, 'donor_id' );
569 605 $donor_ids = implode( ',', array_map( 'intval', $donor_ids ) );
570 - $where .= "AND {$this->table_name}.id IN ({$donor_ids})";
606 + $where .= "AND {$this->table_name}.id IN ({$donor_ids})";
571 607 } else {
572 608 $where .= "AND {$this->table_name}.id IN ('0')";
573 609 }
574 610 }
@@ -574,5 +610,84 @@
574 610 }
575 611
576 612 return $where;
577 613 }
614 +
615 + /**
616 + * If querying a specific date, add the proper filters.
617 + * Note: This function currently only accept dates with admin defined core date format
618 + *
619 + * @since 2.4.0
620 + * @access public
621 + *
622 + * @return void
623 + */
624 + public function date_filter_pre() {
625 + if (
626 + ! empty( $this->args['date_query'] )
627 + || empty( $this->args['start_date'] )
628 + || empty( $this->args['end_date'] )
629 + ) {
630 + return;
631 + }
632 +
633 + $date_query = [];
634 +
635 + if ( ! empty( $this->args['start_date'] ) ) {
636 + $date_query['after'] = date(
637 + 'Y-m-d H:i:s',
638 + is_numeric( $this->args['start_date'] )
639 + ? $this->args['start_date']
640 + : strtotime( $this->args['start_date'] )
641 + );
642 + }
643 +
644 + if ( ! empty( $this->args['end_date'] ) ) {
645 + $date_query['before'] = date(
646 + 'Y-m-d H:i:s',
647 + is_numeric( $this->args['end_date'] )
648 + ? $this->args['end_date']
649 + : strtotime( $this->args['end_date'] )
650 + );
651 + }
652 +
653 + // Include Start Date and End Date while querying.
654 + $date_query['inclusive'] = true;
655 +
656 + $this->__set( 'date_query', $date_query );
657 + }
658 +
659 + /**
660 + * Update donors meta cache
661 + *
662 + * @since 2.5.0
663 + * @access private
664 + *
665 + * @param array $donor_ids
666 + */
667 + public static function update_meta_cache( $donor_ids ) {
668 + // Exit.
669 + if ( empty( $donor_ids ) ) {
670 + return;
671 + }
672 +
673 + update_meta_cache( Give()->donor_meta->get_meta_type(), $donor_ids );
674 + }
675 +
676 + /**
677 + * Set a query variable.
678 + *
679 + * @since 2.4.0
680 + * @access public
681 + *
682 + * @param $query_var
683 + * @param $value
684 + */
685 + public function __set( $query_var, $value ) {
686 + if ( in_array( $query_var, [ 'meta_query', 'tax_query' ] ) ) {
687 + $this->args[ $query_var ][] = $value;
688 + } else {
689 + $this->args[ $query_var ] = $value;
690 + }
691 + }
692 +
578 693 }