WordPress.org

Make WordPress Core

Ticket #44169: 44169.3.diff

File 44169.3.diff, 4.3 KB (added by spacedmonkey, 18 months ago)
  • src/wp-includes/class-wp-user-query.php

     
    592592
    593593                $qv =& $this->query_vars;
    594594
    595                 $this->request = "SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit";
     595                /**
     596                 * Filters the users array before the query takes place.
     597                 *
     598                 * Return a non-null value to bypass WordPress's default user queries.
     599                 * Filtering functions that require pagination information are encouraged to set
     600                 * the `total_users` property of the WP_User_Query object, passed to the filter
     601                 * by reference. If WP_User_Query does not perform a database query, it will not
     602                 * have enough information to generate these values itself.
     603                 *
     604                 * @since 5.0.1
     605                 *
     606                 * @param array|null $results Return an array of user data to short-circuit WP's user query or null to allow WP to run its normal queries.
     607                 * @param WP_User_Query $this The WP_User_Query instance (passed by reference).
     608                 */
     609                $this->results = apply_filters_ref_array( 'users_pre_query', array( null, &$this ) );
    596610
    597                 if ( is_array( $qv['fields'] ) || 'all' == $qv['fields'] ) {
    598                         $this->results = $wpdb->get_results( $this->request );
    599                 } else {
    600                         $this->results = $wpdb->get_col( $this->request );
    601                 }
     611                if ( null === $this->results ) {
     612                        $this->request = "SELECT $this->query_fields $this->query_from $this->query_where $this->query_orderby $this->query_limit";
    602613
    603                 if ( isset( $qv['count_total'] ) && $qv['count_total'] ) {
    604                         /**
    605                          * Filters SELECT FOUND_ROWS() query for the current WP_User_Query instance.
    606                          *
    607                          * @since 3.2.0
    608                          * @since 4.9.9 Added the `$this` parameter.
    609                          *
    610                          * @global wpdb $wpdb WordPress database abstraction object.
    611                          *
    612                          * @param string $sql         The SELECT FOUND_ROWS() query for the current WP_User_Query.
    613                          * @param WP_User_Query $this The current WP_User_Query instance.
    614                          */
    615                         $found_users_query = apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()', $this );
     614                        if ( is_array( $qv['fields'] ) || 'all' == $qv['fields'] ) {
     615                                $this->results = $wpdb->get_results( $this->request );
     616                        } else {
     617                                $this->results = $wpdb->get_col( $this->request );
     618                        }
    616619
    617                         $this->total_users = (int) $wpdb->get_var( $found_users_query );
     620                        if ( isset( $qv['count_total'] ) && $qv['count_total'] ) {
     621                                /**
     622                                 * Filters SELECT FOUND_ROWS() query for the current WP_User_Query instance.
     623                                 *
     624                                 * @since 3.2.0
     625                                 * @since 5.0.1 Added the `$this` parameter.
     626                                 *
     627                                 * @global wpdb $wpdb WordPress database abstraction object.
     628                                 *
     629                                 * @param string $sql The SELECT FOUND_ROWS() query for the current WP_User_Query.
     630                                 * @param WP_User_Query $this The current WP_User_Query instance.
     631                                 */
     632                                $found_users_query = apply_filters( 'found_users_query', 'SELECT FOUND_ROWS()', $this );
     633
     634                                $this->total_users = (int) $wpdb->get_var( $found_users_query );
     635                        }
    618636                }
    619637
    620638                if ( ! $this->results ) {
  • tests/phpunit/tests/user/query.php

     
    16901690                /* must not include user that has same string in other fields */
    16911691                $this->assertEquals( array(), $ids );
    16921692        }
     1693
     1694        /**
     1695         * @ticket 44169
     1696         */
     1697        public function test_users_pre_query_filter_should_bypass_database_query() {
     1698                global $wpdb;
     1699
     1700                add_filter( 'users_pre_query', array( __CLASS__, 'filter_users_pre_query' ), 10, 2 );
     1701
     1702                $num_queries = $wpdb->num_queries;
     1703                $q           = new WP_User_Query(
     1704                        array(
     1705                                'fields' => 'ID',
     1706                        )
     1707                );
     1708
     1709                remove_filter( 'users_pre_query', array( __CLASS__, 'filter_users_pre_query' ), 10, 2 );
     1710
     1711                // Make sure no queries were executed.
     1712                $this->assertSame( $num_queries, $wpdb->num_queries );
     1713
     1714                // We manually inserted a non-existing user and overrode the results with it.
     1715                $this->assertSame( array( 555 ), $q->results );
     1716
     1717                // Make sure manually setting total_users doesn't get overwritten.
     1718                $this->assertEquals( 1, $q->total_users );
     1719        }
     1720
     1721        public static function filter_users_pre_query( $posts, $query ) {
     1722                $query->total_users = 1;
     1723
     1724                return array( 555 );
     1725        }
    16931726}