Skip to:
Content

bbPress.org


Ignore:
Timestamp:
02/09/2020 07:49:50 PM (5 years ago)
Author:
johnjamesjacoby
Message:

Suggestions: various performance improvements & user request checks.

This commit adds a number of code changes surrounding admin-area topic & user suggestions:

  • Limits to 10 results by default
  • Prevents superfluous count queries, and taxonomy & meta prefetching
  • Fixes several UX bugs with suggesting users, specifically around single-digit user IDs and miscellaneous allowed characters
  • Fixes an unintended behavior that allowed non-super moderators to search for users by email address (props mirror12k)
  • Fixes incorrect wp_die() contents when no results were available, causing a 0 to be displayed instead of nothing
  • Adds documentation where it was previously lacking
  • Adds a small bit of user input sanitization & trimming, since these methods are already being scrutinized

For 2.7, trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/includes/admin/classes/class-bbp-admin.php

    r7006 r7070  
    892892    public function suggest_topic() {
    893893
    894         // Bail early if no request
    895         if ( empty( $_REQUEST['q'] ) ) {
    896             wp_die( '0' );
     894        // Do some very basic request checking
     895        $request = ! empty( $_REQUEST['q'] )
     896            ? trim( $_REQUEST['q'] )
     897            : '';
     898
     899        // Bail early if empty request
     900        if ( empty( $request ) ) {
     901            wp_die();
    897902        }
    898903
    899904        // Bail if user cannot moderate - only moderators can change hierarchy
    900905        if ( ! current_user_can( 'moderate' ) ) {
    901             wp_die( '0' );
     906            wp_die();
    902907        }
    903908
     
    905910        check_ajax_referer( 'bbp_suggest_topic_nonce' );
    906911
     912        // Allow the maximum number of results to be filtered
     913        $number = (int) apply_filters( 'bbp_suggest_topic_count', 10 );
     914
    907915        // Try to get some topics
    908916        $topics = get_posts( array(
    909             's'         => bbp_db()->esc_like( $_REQUEST['q'] ),
    910             'post_type' => bbp_get_topic_post_type()
     917            's'              => bbp_db()->esc_like( $request ),
     918            'post_type'      => bbp_get_topic_post_type(),
     919            'posts_per_page' => $number,
     920
     921            // Performance
     922            'nopaging'               => true,
     923            'suppress_filters'       => true,
     924            'update_post_term_cache' => false,
     925            'update_post_meta_cache' => false,
     926            'ignore_sticky_posts'    => true,
     927            'no_found_rows'          => true
    911928        ) );
    912929
     
    927944    public function suggest_user() {
    928945
    929         // Bail early if no request
    930         if ( empty( $_REQUEST['q'] ) ) {
    931             wp_die( '0' );
    932         }
    933 
    934         // Bail if user cannot moderate - only moderators can change authorship
     946        // Do some very basic request checking
     947        $request = ! empty( $_REQUEST['q'] )
     948            ? trim( $_REQUEST['q'] )
     949            : '';
     950
     951        // Bail early if empty request
     952        if ( empty( $request ) ) {
     953            wp_die();
     954        }
     955
     956        // Bail if user cannot moderate
    935957        if ( ! current_user_can( 'moderate' ) ) {
    936             wp_die( '0' );
     958            wp_die();
    937959        }
    938960
     
    940962        check_ajax_referer( 'bbp_suggest_user_nonce' );
    941963
    942         // Try to get some users
     964        // Fields to retrieve & search by
     965        $fields = $search = array( 'ID', 'user_nicename' );
     966
     967        // Keymasters & Super-Mods can also search by email
     968        if ( current_user_can( 'keep_gate' ) || bbp_allow_super_mods() ) {
     969
     970            // Add user_email to searchable columns
     971            array_push( $search, 'user_email' );
     972
     973            // Unstrict to also allow some email characters
     974            $strict = false;
     975
     976        // Strict sanitizing if not Keymaster or Super-Mod
     977        } else {
     978            $strict = true;
     979        }
     980
     981        // Sanitize the request value (possibly not strictly)
     982        $suggest = sanitize_user( $request, $strict );
     983
     984        // Bail if searching for invalid user string
     985        if ( empty( $suggest ) ) {
     986            wp_die();
     987        }
     988
     989        // These single characters should not trigger a user query
     990        $disallowed_single_chars = array( '@', '.', '_', '-', '+', '!', '#', '$', '%', '&', '\\', '*', '+', '/', '=', '?', '^', '`', '{', '|', '}', '~' );
     991
     992        // Bail if request is only for the above single characters
     993        if ( in_array( $suggest, $disallowed_single_chars, true ) ) {
     994            wp_die();
     995        }
     996
     997        // Allow the maximum number of results to be filtered
     998        $number = (int) apply_filters( 'bbp_suggest_user_count', 10 );
     999
     1000        // Query database for users based on above criteria
    9431001        $users_query = new WP_User_Query( array(
    944             'search'         => '*' . bbp_db()->esc_like( $_REQUEST['q'] ) . '*',
    945             'fields'         => array( 'ID', 'user_nicename' ),
    946             'search_columns' => array( 'ID', 'user_nicename', 'user_email' ),
    947             'orderby'        => 'ID'
     1002            'search'         => '*' . bbp_db()->esc_like( $suggest ) . '*',
     1003            'fields'         => $fields,
     1004            'search_columns' => $search,
     1005            'orderby'        => 'ID',
     1006            'number'         => $number,
     1007            'count_total'    => false
    9481008        ) );
    9491009
    950         // If we found some users, loop through and display them
     1010        // If we found some users, loop through and output them to the AJAX
    9511011        if ( ! empty( $users_query->results ) ) {
    9521012            foreach ( (array) $users_query->results as $user ) {
Note: See TracChangeset for help on using the changeset viewer.